From 6c5f0cba0cd83f6345b6a890a4d35e7cf4d95a65 Mon Sep 17 00:00:00 2001 From: Cristian Capozucco Date: Wed, 6 Sep 2023 11:19:35 +0200 Subject: [PATCH] SYNCOPE-1775: logoutType can now be set to CAS services (#513) --- .../ClientAppModalPanelBuilder.java | 6 +++++ .../ClientAppDirectoryPanel.properties | 1 + .../ClientAppDirectoryPanel_fr_CA.properties | 1 + .../ClientAppDirectoryPanel_it.properties | 1 + .../ClientAppDirectoryPanel_ja.properties | 1 + .../ClientAppDirectoryPanel_pt_BR.properties | 1 + .../ClientAppDirectoryPanel_ru.properties | 1 + .../syncope/common/lib/to/ClientAppTO.java | 13 ++++++++++ .../syncope/common/lib/types/LogoutType.java | 25 +++++++++++++++++++ .../persistence/api/entity/am/ClientApp.java | 5 ++++ .../jpa/entity/am/AbstractClientApp.java | 16 ++++++++++++ .../java/data/ClientAppDataBinderImpl.java | 2 ++ .../mapping/AbstractClientAppMapper.java | 3 +++ .../wa/starter/WAServiceRegistryTest.java | 7 +++++- 14 files changed, 82 insertions(+), 1 deletion(-) create mode 100644 common/am/lib/src/main/java/org/apache/syncope/common/lib/types/LogoutType.java diff --git a/client/am/console/src/main/java/org/apache/syncope/client/console/clientapps/ClientAppModalPanelBuilder.java b/client/am/console/src/main/java/org/apache/syncope/client/console/clientapps/ClientAppModalPanelBuilder.java index 4e15aaec1c..39e3451f67 100644 --- a/client/am/console/src/main/java/org/apache/syncope/client/console/clientapps/ClientAppModalPanelBuilder.java +++ b/client/am/console/src/main/java/org/apache/syncope/client/console/clientapps/ClientAppModalPanelBuilder.java @@ -54,6 +54,7 @@ import org.apache.syncope.common.lib.to.ClientAppTO; import org.apache.syncope.common.lib.to.RealmTO; import org.apache.syncope.common.lib.types.ClientAppType; +import org.apache.syncope.common.lib.types.LogoutType; import org.apache.syncope.common.lib.types.OIDCGrantType; import org.apache.syncope.common.lib.types.OIDCResponseType; import org.apache.syncope.common.lib.types.OIDCScope; @@ -254,6 +255,11 @@ protected Iterator getChoices(final String input) { ((AbstractSingleSelectChoice) ticketExpirationPolicy.getField()).setNullValid(true); fields.add(ticketExpirationPolicy); + AjaxDropDownChoicePanel logoutType = new AjaxDropDownChoicePanel<>( + "field", "logoutType", new PropertyModel<>(clientAppTO, "logoutType"), false); + logoutType.setChoices(List.of(LogoutType.values())); + fields.add(logoutType); + switch (type) { case CASSP: fields.add(new AjaxTextFieldPanel( diff --git a/client/am/console/src/main/resources/org/apache/syncope/client/console/clientapps/ClientAppDirectoryPanel.properties b/client/am/console/src/main/resources/org/apache/syncope/client/console/clientapps/ClientAppDirectoryPanel.properties index 6a8384cd73..8a90e272bd 100644 --- a/client/am/console/src/main/resources/org/apache/syncope/client/console/clientapps/ClientAppDirectoryPanel.properties +++ b/client/am/console/src/main/resources/org/apache/syncope/client/console/clientapps/ClientAppDirectoryPanel.properties @@ -66,3 +66,4 @@ compose.title=username attribute provider usernameAttributeProviderConf.title=Username Attribute Provider for ${name} ticketExpirationPolicy=Ticket Expiration Policy auditHistory.title=Configuration history +logoutType=Logout Type diff --git a/client/am/console/src/main/resources/org/apache/syncope/client/console/clientapps/ClientAppDirectoryPanel_fr_CA.properties b/client/am/console/src/main/resources/org/apache/syncope/client/console/clientapps/ClientAppDirectoryPanel_fr_CA.properties index 54ad87ed30..afb22b5b51 100644 --- a/client/am/console/src/main/resources/org/apache/syncope/client/console/clientapps/ClientAppDirectoryPanel_fr_CA.properties +++ b/client/am/console/src/main/resources/org/apache/syncope/client/console/clientapps/ClientAppDirectoryPanel_fr_CA.properties @@ -66,3 +66,4 @@ compose.title=username attribute provider usernameAttributeProviderConf.title=Username Attribute Provider for ${name} ticketExpirationPolicy=Ticket Expiration Policy auditHistory.title=Historique de configuration +logoutType=Logout Type diff --git a/client/am/console/src/main/resources/org/apache/syncope/client/console/clientapps/ClientAppDirectoryPanel_it.properties b/client/am/console/src/main/resources/org/apache/syncope/client/console/clientapps/ClientAppDirectoryPanel_it.properties index 0759c06a0a..0ca1bf1e08 100644 --- a/client/am/console/src/main/resources/org/apache/syncope/client/console/clientapps/ClientAppDirectoryPanel_it.properties +++ b/client/am/console/src/main/resources/org/apache/syncope/client/console/clientapps/ClientAppDirectoryPanel_it.properties @@ -66,3 +66,4 @@ compose.title=username attribute provider usernameAttributeProviderConf.title=Username Attribute Provider per ${name} ticketExpirationPolicy=Politica Ticket Expiration auditHistory.title=Storico delle configurazioni +logoutType=Tipo Logout diff --git a/client/am/console/src/main/resources/org/apache/syncope/client/console/clientapps/ClientAppDirectoryPanel_ja.properties b/client/am/console/src/main/resources/org/apache/syncope/client/console/clientapps/ClientAppDirectoryPanel_ja.properties index f0d9b3aa67..824c6a4abe 100644 --- a/client/am/console/src/main/resources/org/apache/syncope/client/console/clientapps/ClientAppDirectoryPanel_ja.properties +++ b/client/am/console/src/main/resources/org/apache/syncope/client/console/clientapps/ClientAppDirectoryPanel_ja.properties @@ -66,3 +66,4 @@ compose.title=username attribute provider usernameAttributeProviderConf.title=Username Attribute Provider for ${name} ticketExpirationPolicy=Ticket Expiration Policy auditHistory.title=\u8a2d\u5b9a\u5c65\u6b74 +logoutType=Logout Type diff --git a/client/am/console/src/main/resources/org/apache/syncope/client/console/clientapps/ClientAppDirectoryPanel_pt_BR.properties b/client/am/console/src/main/resources/org/apache/syncope/client/console/clientapps/ClientAppDirectoryPanel_pt_BR.properties index e222637a24..cf375f5886 100644 --- a/client/am/console/src/main/resources/org/apache/syncope/client/console/clientapps/ClientAppDirectoryPanel_pt_BR.properties +++ b/client/am/console/src/main/resources/org/apache/syncope/client/console/clientapps/ClientAppDirectoryPanel_pt_BR.properties @@ -66,3 +66,4 @@ compose.title=username attribute provider usernameAttributeProviderConf.title=Username Attribute Provider for ${name} ticketExpirationPolicy=Ticket Expiration Policy auditHistory.title=Hist\u00f3rico de configura\u00e7\u00e3o +logoutType=Logout Type diff --git a/client/am/console/src/main/resources/org/apache/syncope/client/console/clientapps/ClientAppDirectoryPanel_ru.properties b/client/am/console/src/main/resources/org/apache/syncope/client/console/clientapps/ClientAppDirectoryPanel_ru.properties index 7f5907c8dc..ffed062b7e 100644 --- a/client/am/console/src/main/resources/org/apache/syncope/client/console/clientapps/ClientAppDirectoryPanel_ru.properties +++ b/client/am/console/src/main/resources/org/apache/syncope/client/console/clientapps/ClientAppDirectoryPanel_ru.properties @@ -67,3 +67,4 @@ compose.title=username attribute provider usernameAttributeProviderConf.title=Username Attribute Provider for ${name} ticketExpirationPolicy=Ticket Expiration Policy auditHistory.title=\u0418\u0441\u0442\u043e\u0440\u0438\u044f \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438 +logoutType=Logout Type diff --git a/common/am/lib/src/main/java/org/apache/syncope/common/lib/to/ClientAppTO.java b/common/am/lib/src/main/java/org/apache/syncope/common/lib/to/ClientAppTO.java index e211d7d84e..95291f12da 100644 --- a/common/am/lib/src/main/java/org/apache/syncope/common/lib/to/ClientAppTO.java +++ b/common/am/lib/src/main/java/org/apache/syncope/common/lib/to/ClientAppTO.java @@ -31,6 +31,7 @@ import org.apache.commons.lang3.builder.HashCodeBuilder; import org.apache.syncope.common.lib.Attr; import org.apache.syncope.common.lib.clientapps.UsernameAttributeProviderConf; +import org.apache.syncope.common.lib.types.LogoutType; @JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, include = JsonTypeInfo.As.EXISTING_PROPERTY, property = "_class") @JsonPropertyOrder(value = { "_class", "key", "description" }) @@ -73,6 +74,8 @@ public abstract class ClientAppTO implements NamedEntityTO { private String ticketExpirationPolicy; private final List properties = new ArrayList<>(); + + private LogoutType logoutType = LogoutType.NONE; @Schema(name = "_class", requiredMode = Schema.RequiredMode.REQUIRED) public abstract String getDiscriminator(); @@ -204,6 +207,14 @@ public List getProperties() { return properties; } + public LogoutType getLogoutType() { + return logoutType; + } + + public void setLogoutType(final LogoutType logoutType) { + this.logoutType = logoutType; + } + @Override public int hashCode() { return new HashCodeBuilder() @@ -223,6 +234,7 @@ public int hashCode() { .append(attrReleasePolicy) .append(ticketExpirationPolicy) .append(properties) + .append(logoutType) .toHashCode(); } @@ -255,6 +267,7 @@ public boolean equals(final Object obj) { .append(this.attrReleasePolicy, rhs.attrReleasePolicy) .append(this.ticketExpirationPolicy, rhs.ticketExpirationPolicy) .append(this.properties, rhs.properties) + .append(this.logoutType, rhs.logoutType) .isEquals(); } } diff --git a/common/am/lib/src/main/java/org/apache/syncope/common/lib/types/LogoutType.java b/common/am/lib/src/main/java/org/apache/syncope/common/lib/types/LogoutType.java new file mode 100644 index 0000000000..19dd791b51 --- /dev/null +++ b/common/am/lib/src/main/java/org/apache/syncope/common/lib/types/LogoutType.java @@ -0,0 +1,25 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.syncope.common.lib.types; + +public enum LogoutType { + NONE, + BACK_CHANNEL, + FRONT_CHANNEL +} diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/am/ClientApp.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/am/ClientApp.java index 493b74c5fe..e79d990ce4 100644 --- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/am/ClientApp.java +++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/am/ClientApp.java @@ -21,6 +21,7 @@ import java.util.List; import org.apache.syncope.common.lib.Attr; import org.apache.syncope.common.lib.clientapps.UsernameAttributeProviderConf; +import org.apache.syncope.common.lib.types.LogoutType; import org.apache.syncope.core.persistence.api.entity.Entity; import org.apache.syncope.core.persistence.api.entity.Realm; import org.apache.syncope.core.persistence.api.entity.policy.AccessPolicy; @@ -85,4 +86,8 @@ public interface ClientApp extends Entity { List getProperties(); void setProperties(List properties); + + LogoutType getLogoutType(); + + void setLogoutType(LogoutType logoutType); } diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/am/AbstractClientApp.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/am/AbstractClientApp.java index 860ce43690..03943b043e 100644 --- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/am/AbstractClientApp.java +++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/am/AbstractClientApp.java @@ -23,12 +23,15 @@ import java.util.List; import java.util.Optional; import javax.persistence.Column; +import javax.persistence.EnumType; +import javax.persistence.Enumerated; import javax.persistence.FetchType; import javax.persistence.Lob; import javax.persistence.ManyToOne; import javax.persistence.MappedSuperclass; import org.apache.syncope.common.lib.Attr; import org.apache.syncope.common.lib.clientapps.UsernameAttributeProviderConf; +import org.apache.syncope.common.lib.types.LogoutType; import org.apache.syncope.core.persistence.api.entity.Realm; import org.apache.syncope.core.persistence.api.entity.am.ClientApp; import org.apache.syncope.core.persistence.api.entity.policy.AccessPolicy; @@ -88,6 +91,9 @@ public class AbstractClientApp extends AbstractGeneratedKeyEntity implements Cli @Lob private String properties; + @Enumerated(EnumType.STRING) + private LogoutType logoutType; + @Override public Long getClientAppId() { return clientAppId; @@ -235,4 +241,14 @@ public List getProperties() { public void setProperties(final List properties) { this.properties = POJOHelper.serialize(properties); } + + @Override + public LogoutType getLogoutType() { + return this.logoutType; + } + + @Override + public void setLogoutType(final LogoutType logoutType) { + this.logoutType = logoutType; + } } diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/ClientAppDataBinderImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/ClientAppDataBinderImpl.java index 7d695694d9..50496833ad 100644 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/ClientAppDataBinderImpl.java +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/ClientAppDataBinderImpl.java @@ -164,6 +164,7 @@ protected void copyToTO(final ClientApp clientApp, final ClientAppTO clientAppTO clientAppTO.setInformationUrl(clientApp.getInformationUrl()); clientAppTO.setPrivacyUrl(clientApp.getPrivacyUrl()); clientAppTO.setUsernameAttributeProviderConf(clientApp.getUsernameAttributeProviderConf()); + clientAppTO.setLogoutType(clientApp.getLogoutType()); clientAppTO.setAuthPolicy(Optional.ofNullable(clientApp.getAuthPolicy()). map(AuthPolicy::getKey).orElse(null)); @@ -343,5 +344,6 @@ protected void copyToEntity(final ClientApp clientApp, final ClientAppTO clientA } clientApp.setProperties(clientAppTO.getProperties()); + clientApp.setLogoutType(clientAppTO.getLogoutType()); } } diff --git a/wa/starter/src/main/java/org/apache/syncope/wa/starter/mapping/AbstractClientAppMapper.java b/wa/starter/src/main/java/org/apache/syncope/wa/starter/mapping/AbstractClientAppMapper.java index f3ef455a58..e2b003fe7a 100644 --- a/wa/starter/src/main/java/org/apache/syncope/wa/starter/mapping/AbstractClientAppMapper.java +++ b/wa/starter/src/main/java/org/apache/syncope/wa/starter/mapping/AbstractClientAppMapper.java @@ -29,6 +29,7 @@ import org.apereo.cas.services.RegisteredServiceAccessStrategy; import org.apereo.cas.services.RegisteredServiceAttributeReleasePolicy; import org.apereo.cas.services.RegisteredServiceAuthenticationPolicy; +import org.apereo.cas.services.RegisteredServiceLogoutType; import org.apereo.cas.services.RegisteredServiceMultifactorPolicy; import org.apereo.cas.services.RegisteredServiceProperty; import org.apereo.cas.services.RegisteredServiceProxyGrantingTicketExpirationPolicy; @@ -57,6 +58,8 @@ protected void setCommon(final BaseWebBasedRegisteredService service, final Clie (existing, replacement) -> existing)); service.setProperties(properties); } + + service.setLogoutType(RegisteredServiceLogoutType.valueOf(clientApp.getLogoutType().name())); } protected void setPolicies( diff --git a/wa/starter/src/test/java/org/apache/syncope/wa/starter/WAServiceRegistryTest.java b/wa/starter/src/test/java/org/apache/syncope/wa/starter/WAServiceRegistryTest.java index 7eaff948e3..3cf90ef1b6 100644 --- a/wa/starter/src/test/java/org/apache/syncope/wa/starter/WAServiceRegistryTest.java +++ b/wa/starter/src/test/java/org/apache/syncope/wa/starter/WAServiceRegistryTest.java @@ -38,6 +38,7 @@ import org.apache.syncope.common.lib.to.AuthModuleTO; import org.apache.syncope.common.lib.to.OIDCRPClientAppTO; import org.apache.syncope.common.lib.to.SAML2SPClientAppTO; +import org.apache.syncope.common.lib.types.LogoutType; import org.apache.syncope.common.lib.types.OIDCGrantType; import org.apache.syncope.common.lib.types.OIDCResponseType; import org.apache.syncope.common.lib.types.OIDCSubjectType; @@ -54,6 +55,7 @@ import org.apereo.cas.services.RegisteredService; import org.apereo.cas.services.RegisteredServiceAccessStrategy; import org.apereo.cas.services.RegisteredServiceDelegatedAuthenticationPolicy; +import org.apereo.cas.services.RegisteredServiceLogoutType; import org.apereo.cas.services.ServicesManager; import org.apereo.cas.support.saml.services.SamlRegisteredService; import org.apereo.cas.util.RandomUtils; @@ -75,6 +77,7 @@ private static OIDCRPClientAppTO buildOIDCRP() { oidcrpTO.setSubjectType(OIDCSubjectType.PUBLIC); oidcrpTO.getSupportedGrantTypes().add(OIDCGrantType.password); oidcrpTO.getSupportedResponseTypes().add(OIDCResponseType.CODE); + oidcrpTO.setLogoutType(LogoutType.BACK_CHANNEL); return oidcrpTO; } @@ -89,7 +92,7 @@ private static SAML2SPClientAppTO buildSAML2SP() { saml2spto.setRequiredNameIdFormat(SAML2SPNameId.EMAIL_ADDRESS); saml2spto.setEncryptionOptional(true); saml2spto.setEncryptAssertions(true); - + saml2spto.setLogoutType(LogoutType.BACK_CHANNEL); return saml2spto; } @@ -185,6 +188,7 @@ public void addClientApp() { assertTrue(((AnyAuthenticationHandlerRegisteredServiceAuthenticationPolicyCriteria) oidc. getAuthenticationPolicy().getCriteria()).isTryAll()); assertTrue(oidc.getAttributeReleasePolicy() instanceof ChainingAttributeReleasePolicy); + assertEquals(RegisteredServiceLogoutType.valueOf(oidcrpto.getLogoutType().name()), oidc.getLogoutType()); // 5. more client with different attributes waClientApp = new WAClientApp(); @@ -208,6 +212,7 @@ public void addClientApp() { assertTrue(saml.getAuthenticationPolicy().getRequiredAuthenticationHandlers().contains("TestAuthModule")); assertNotNull(found.getAccessStrategy()); assertTrue(saml.getAttributeReleasePolicy() instanceof ChainingAttributeReleasePolicy); + assertEquals(RegisteredServiceLogoutType.valueOf(samlspto.getLogoutType().name()), saml.getLogoutType()); waClientApp = new WAClientApp(); waClientApp.setClientAppTO(buildSAML2SP());