From a2fb35cbeb8bb3d48370cb45c91afe9b195dabd9 Mon Sep 17 00:00:00 2001 From: Thisara-Welmilla Date: Thu, 7 Nov 2024 12:09:52 +0530 Subject: [PATCH 01/10] Update APIs to support custom authentication management. --- .../idp/v1/model/AuthenticationType.java | 166 +++++++++++ .../api/server/idp/v1/model/Endpoint.java | 120 ++++++++ .../idp/v1/model/FederatedAuthenticator.java | 26 +- .../FederatedAuthenticatorPUTRequest.java | 26 +- .../FederatedUserDefinedAuthenticator.java | 271 ++++++++++++++++++ ...tedUserDefinedAuthenticatorPUTRequest.java | 162 +++++++++++ .../v1/model/MetaFederatedAuthenticator.java | 26 +- .../v1/core/ServerIdpManagementService.java | 93 +++++- .../src/main/resources/idp.yaml | 36 +++ 9 files changed, 908 insertions(+), 18 deletions(-) create mode 100644 components/org.wso2.carbon.identity.api.server.idp/org.wso2.carbon.identity.api.server.idp.v1/src/gen/java/org/wso2/carbon/identity/api/server/idp/v1/model/AuthenticationType.java create mode 100644 components/org.wso2.carbon.identity.api.server.idp/org.wso2.carbon.identity.api.server.idp.v1/src/gen/java/org/wso2/carbon/identity/api/server/idp/v1/model/Endpoint.java create mode 100644 components/org.wso2.carbon.identity.api.server.idp/org.wso2.carbon.identity.api.server.idp.v1/src/gen/java/org/wso2/carbon/identity/api/server/idp/v1/model/FederatedUserDefinedAuthenticator.java create mode 100644 components/org.wso2.carbon.identity.api.server.idp/org.wso2.carbon.identity.api.server.idp.v1/src/gen/java/org/wso2/carbon/identity/api/server/idp/v1/model/FederatedUserDefinedAuthenticatorPUTRequest.java diff --git a/components/org.wso2.carbon.identity.api.server.idp/org.wso2.carbon.identity.api.server.idp.v1/src/gen/java/org/wso2/carbon/identity/api/server/idp/v1/model/AuthenticationType.java b/components/org.wso2.carbon.identity.api.server.idp/org.wso2.carbon.identity.api.server.idp.v1/src/gen/java/org/wso2/carbon/identity/api/server/idp/v1/model/AuthenticationType.java new file mode 100644 index 0000000000..1b2660df61 --- /dev/null +++ b/components/org.wso2.carbon.identity.api.server.idp/org.wso2.carbon.identity.api.server.idp.v1/src/gen/java/org/wso2/carbon/identity/api/server/idp/v1/model/AuthenticationType.java @@ -0,0 +1,166 @@ +/* + * Copyright (c) 2024, WSO2 LLC. (http://www.wso2.com). + * + * WSO2 LLC. 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.wso2.carbon.identity.api.server.idp.v1.model; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import javax.validation.constraints.*; + + +import io.swagger.annotations.*; +import java.util.Objects; +import javax.validation.Valid; +import javax.xml.bind.annotation.*; + +public class AuthenticationType { + + +@XmlType(name="TypeEnum") +@XmlEnum(String.class) +public enum TypeEnum { + + @XmlEnumValue("NONE") NONE(String.valueOf("NONE")), @XmlEnumValue("BEARER") BEARER(String.valueOf("BEARER")), @XmlEnumValue("API_KEY") API_KEY(String.valueOf("API_KEY")), @XmlEnumValue("BASIC") BASIC(String.valueOf("BASIC")); + + + private String value; + + TypeEnum(String v) { + value = v; + } + + public String value() { + return value; + } + + @Override + public String toString() { + return String.valueOf(value); + } + + public static TypeEnum fromValue(String value) { + for (TypeEnum b : TypeEnum.values()) { + if (b.value.equals(value)) { + return b; + } + } + throw new IllegalArgumentException("Unexpected value '" + value + "'"); + } +} + + private TypeEnum type; + private Map properties = new HashMap<>(); + + + /** + **/ + public AuthenticationType type(TypeEnum type) { + + this.type = type; + return this; + } + + @ApiModelProperty(example = "BASIC", required = true, value = "") + @JsonProperty("type") + @Valid + @NotNull(message = "Property type cannot be null.") + + public TypeEnum getType() { + return type; + } + public void setType(TypeEnum type) { + this.type = type; + } + + /** + **/ + public AuthenticationType properties(Map properties) { + + this.properties = properties; + return this; + } + + @ApiModelProperty(example = "{\"username\":\"auth_username\",\"password\":\"auth_password\"}", required = true, value = "") + @JsonProperty("properties") + @Valid + @NotNull(message = "Property properties cannot be null.") + + public Map getProperties() { + return properties; + } + public void setProperties(Map properties) { + this.properties = properties; + } + + + public AuthenticationType putPropertiesItem(String key, Object propertiesItem) { + this.properties.put(key, propertiesItem); + return this; + } + + + + @Override + public boolean equals(java.lang.Object o) { + + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + AuthenticationType authenticationType = (AuthenticationType) o; + return Objects.equals(this.type, authenticationType.type) && + Objects.equals(this.properties, authenticationType.properties); + } + + @Override + public int hashCode() { + return Objects.hash(type, properties); + } + + @Override + public String toString() { + + StringBuilder sb = new StringBuilder(); + sb.append("class AuthenticationType {\n"); + + sb.append(" type: ").append(toIndentedString(type)).append("\n"); + sb.append(" properties: ").append(toIndentedString(properties)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(java.lang.Object o) { + + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n"); + } +} + diff --git a/components/org.wso2.carbon.identity.api.server.idp/org.wso2.carbon.identity.api.server.idp.v1/src/gen/java/org/wso2/carbon/identity/api/server/idp/v1/model/Endpoint.java b/components/org.wso2.carbon.identity.api.server.idp/org.wso2.carbon.identity.api.server.idp.v1/src/gen/java/org/wso2/carbon/identity/api/server/idp/v1/model/Endpoint.java new file mode 100644 index 0000000000..477bb8c8ad --- /dev/null +++ b/components/org.wso2.carbon.identity.api.server.idp/org.wso2.carbon.identity.api.server.idp.v1/src/gen/java/org/wso2/carbon/identity/api/server/idp/v1/model/Endpoint.java @@ -0,0 +1,120 @@ +/* + * Copyright (c) 2024, WSO2 LLC. (http://www.wso2.com). + * + * WSO2 LLC. 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.wso2.carbon.identity.api.server.idp.v1.model; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import org.wso2.carbon.identity.api.server.idp.v1.model.AuthenticationType; +import javax.validation.constraints.*; + + +import io.swagger.annotations.*; +import java.util.Objects; +import javax.validation.Valid; +import javax.xml.bind.annotation.*; + +public class Endpoint { + + private String uri; + private AuthenticationType authentication; + + /** + **/ + public Endpoint uri(String uri) { + + this.uri = uri; + return this; + } + + @ApiModelProperty(example = "https://abc.com/token", value = "") + @JsonProperty("uri") + @Valid @Pattern(regexp="^https?://.+") + public String getUri() { + return uri; + } + public void setUri(String uri) { + this.uri = uri; + } + + /** + **/ + public Endpoint authentication(AuthenticationType authentication) { + + this.authentication = authentication; + return this; + } + + @ApiModelProperty(value = "") + @JsonProperty("authentication") + @Valid + public AuthenticationType getAuthentication() { + return authentication; + } + public void setAuthentication(AuthenticationType authentication) { + this.authentication = authentication; + } + + + + @Override + public boolean equals(java.lang.Object o) { + + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + Endpoint endpoint = (Endpoint) o; + return Objects.equals(this.uri, endpoint.uri) && + Objects.equals(this.authentication, endpoint.authentication); + } + + @Override + public int hashCode() { + return Objects.hash(uri, authentication); + } + + @Override + public String toString() { + + StringBuilder sb = new StringBuilder(); + sb.append("class Endpoint {\n"); + + sb.append(" uri: ").append(toIndentedString(uri)).append("\n"); + sb.append(" authentication: ").append(toIndentedString(authentication)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(java.lang.Object o) { + + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n"); + } +} + diff --git a/components/org.wso2.carbon.identity.api.server.idp/org.wso2.carbon.identity.api.server.idp.v1/src/gen/java/org/wso2/carbon/identity/api/server/idp/v1/model/FederatedAuthenticator.java b/components/org.wso2.carbon.identity.api.server.idp/org.wso2.carbon.identity.api.server.idp.v1/src/gen/java/org/wso2/carbon/identity/api/server/idp/v1/model/FederatedAuthenticator.java index 5996d10619..6ceecbd085 100644 --- a/components/org.wso2.carbon.identity.api.server.idp/org.wso2.carbon.identity.api.server.idp.v1/src/gen/java/org/wso2/carbon/identity/api/server/idp/v1/model/FederatedAuthenticator.java +++ b/components/org.wso2.carbon.identity.api.server.idp/org.wso2.carbon.identity.api.server.idp.v1/src/gen/java/org/wso2/carbon/identity/api/server/idp/v1/model/FederatedAuthenticator.java @@ -22,6 +22,7 @@ import io.swagger.annotations.ApiModelProperty; import java.util.ArrayList; import java.util.List; +import org.wso2.carbon.identity.api.server.idp.v1.model.Endpoint; import org.wso2.carbon.identity.api.server.idp.v1.model.Property; import javax.validation.constraints.*; @@ -75,6 +76,7 @@ public static DefinedByEnum fromValue(String value) { private List properties = null; + private Endpoint endpoint; /** **/ @@ -220,7 +222,25 @@ public FederatedAuthenticator addPropertiesItem(Property propertiesItem) { return this; } + /** + **/ + public FederatedAuthenticator endpoint(Endpoint endpoint) { + + this.endpoint = endpoint; + return this; + } + @ApiModelProperty(value = "") + @JsonProperty("endpoint") + @Valid + public Endpoint getEndpoint() { + return endpoint; + } + public void setEndpoint(Endpoint endpoint) { + this.endpoint = endpoint; + } + + @Override public boolean equals(java.lang.Object o) { @@ -238,12 +258,13 @@ public boolean equals(java.lang.Object o) { Objects.equals(this.definedBy, federatedAuthenticator.definedBy) && Objects.equals(this.isDefault, federatedAuthenticator.isDefault) && Objects.equals(this.tags, federatedAuthenticator.tags) && - Objects.equals(this.properties, federatedAuthenticator.properties); + Objects.equals(this.properties, federatedAuthenticator.properties) && + Objects.equals(this.endpoint, federatedAuthenticator.endpoint); } @Override public int hashCode() { - return Objects.hash(authenticatorId, name, isEnabled, definedBy, isDefault, tags, properties); + return Objects.hash(authenticatorId, name, isEnabled, definedBy, isDefault, tags, properties, endpoint); } @Override @@ -259,6 +280,7 @@ public String toString() { sb.append(" isDefault: ").append(toIndentedString(isDefault)).append("\n"); sb.append(" tags: ").append(toIndentedString(tags)).append("\n"); sb.append(" properties: ").append(toIndentedString(properties)).append("\n"); + sb.append(" endpoint: ").append(toIndentedString(endpoint)).append("\n"); sb.append("}"); return sb.toString(); } diff --git a/components/org.wso2.carbon.identity.api.server.idp/org.wso2.carbon.identity.api.server.idp.v1/src/gen/java/org/wso2/carbon/identity/api/server/idp/v1/model/FederatedAuthenticatorPUTRequest.java b/components/org.wso2.carbon.identity.api.server.idp/org.wso2.carbon.identity.api.server.idp.v1/src/gen/java/org/wso2/carbon/identity/api/server/idp/v1/model/FederatedAuthenticatorPUTRequest.java index 685579c64a..db8b737efb 100644 --- a/components/org.wso2.carbon.identity.api.server.idp/org.wso2.carbon.identity.api.server.idp.v1/src/gen/java/org/wso2/carbon/identity/api/server/idp/v1/model/FederatedAuthenticatorPUTRequest.java +++ b/components/org.wso2.carbon.identity.api.server.idp/org.wso2.carbon.identity.api.server.idp.v1/src/gen/java/org/wso2/carbon/identity/api/server/idp/v1/model/FederatedAuthenticatorPUTRequest.java @@ -22,6 +22,7 @@ import io.swagger.annotations.ApiModelProperty; import java.util.ArrayList; import java.util.List; +import org.wso2.carbon.identity.api.server.idp.v1.model.Endpoint; import org.wso2.carbon.identity.api.server.idp.v1.model.Property; import javax.validation.constraints.*; @@ -73,6 +74,7 @@ public static DefinedByEnum fromValue(String value) { private DefinedByEnum definedBy; private List properties = null; + private Endpoint endpoint; /** **/ @@ -190,7 +192,25 @@ public FederatedAuthenticatorPUTRequest addPropertiesItem(Property propertiesIte return this; } + /** + **/ + public FederatedAuthenticatorPUTRequest endpoint(Endpoint endpoint) { + + this.endpoint = endpoint; + return this; + } + @ApiModelProperty(value = "") + @JsonProperty("endpoint") + @Valid + public Endpoint getEndpoint() { + return endpoint; + } + public void setEndpoint(Endpoint endpoint) { + this.endpoint = endpoint; + } + + @Override public boolean equals(java.lang.Object o) { @@ -207,12 +227,13 @@ public boolean equals(java.lang.Object o) { Objects.equals(this.isEnabled, federatedAuthenticatorPUTRequest.isEnabled) && Objects.equals(this.isDefault, federatedAuthenticatorPUTRequest.isDefault) && Objects.equals(this.definedBy, federatedAuthenticatorPUTRequest.definedBy) && - Objects.equals(this.properties, federatedAuthenticatorPUTRequest.properties); + Objects.equals(this.properties, federatedAuthenticatorPUTRequest.properties) && + Objects.equals(this.endpoint, federatedAuthenticatorPUTRequest.endpoint); } @Override public int hashCode() { - return Objects.hash(authenticatorId, name, isEnabled, isDefault, definedBy, properties); + return Objects.hash(authenticatorId, name, isEnabled, isDefault, definedBy, properties, endpoint); } @Override @@ -227,6 +248,7 @@ public String toString() { sb.append(" isDefault: ").append(toIndentedString(isDefault)).append("\n"); sb.append(" definedBy: ").append(toIndentedString(definedBy)).append("\n"); sb.append(" properties: ").append(toIndentedString(properties)).append("\n"); + sb.append(" endpoint: ").append(toIndentedString(endpoint)).append("\n"); sb.append("}"); return sb.toString(); } diff --git a/components/org.wso2.carbon.identity.api.server.idp/org.wso2.carbon.identity.api.server.idp.v1/src/gen/java/org/wso2/carbon/identity/api/server/idp/v1/model/FederatedUserDefinedAuthenticator.java b/components/org.wso2.carbon.identity.api.server.idp/org.wso2.carbon.identity.api.server.idp.v1/src/gen/java/org/wso2/carbon/identity/api/server/idp/v1/model/FederatedUserDefinedAuthenticator.java new file mode 100644 index 0000000000..465eb5d546 --- /dev/null +++ b/components/org.wso2.carbon.identity.api.server.idp/org.wso2.carbon.identity.api.server.idp.v1/src/gen/java/org/wso2/carbon/identity/api/server/idp/v1/model/FederatedUserDefinedAuthenticator.java @@ -0,0 +1,271 @@ +/* + * Copyright (c) 2024, WSO2 LLC. (http://www.wso2.com). + * + * WSO2 LLC. 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.wso2.carbon.identity.api.server.idp.v1.model; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import java.util.ArrayList; +import java.util.List; +import org.wso2.carbon.identity.api.server.idp.v1.model.Endpoint; +import javax.validation.constraints.*; + + +import io.swagger.annotations.*; +import java.util.Objects; +import javax.validation.Valid; +import javax.xml.bind.annotation.*; + +public class FederatedUserDefinedAuthenticator { + + private String authenticatorId; + private String name; + private Boolean isEnabled = false; + +@XmlType(name="DefinedByEnum") +@XmlEnum(String.class) +public enum DefinedByEnum { + + @XmlEnumValue("USER") USER(String.valueOf("USER")); + + + private String value; + + DefinedByEnum(String v) { + value = v; + } + + public String value() { + return value; + } + + @Override + public String toString() { + return String.valueOf(value); + } + + public static DefinedByEnum fromValue(String value) { + for (DefinedByEnum b : DefinedByEnum.values()) { + if (b.value.equals(value)) { + return b; + } + } + throw new IllegalArgumentException("Unexpected value '" + value + "'"); + } +} + + private DefinedByEnum definedBy; + private Boolean isDefault = false; + private List tags = null; + + private Endpoint endpoint; + + /** + **/ + public FederatedUserDefinedAuthenticator authenticatorId(String authenticatorId) { + + this.authenticatorId = authenticatorId; + return this; + } + + @ApiModelProperty(example = "Y3VzdG9tQXV0aGVudGljYXRvcg", required = true, value = "") + @JsonProperty("authenticatorId") + @Valid + @NotNull(message = "Property authenticatorId cannot be null.") + + public String getAuthenticatorId() { + return authenticatorId; + } + public void setAuthenticatorId(String authenticatorId) { + this.authenticatorId = authenticatorId; + } + + /** + **/ + public FederatedUserDefinedAuthenticator name(String name) { + + this.name = name; + return this; + } + + @ApiModelProperty(example = "customAuthenticator", value = "") + @JsonProperty("name") + @Valid + public String getName() { + return name; + } + public void setName(String name) { + this.name = name; + } + + /** + **/ + public FederatedUserDefinedAuthenticator isEnabled(Boolean isEnabled) { + + this.isEnabled = isEnabled; + return this; + } + + @ApiModelProperty(example = "true", value = "") + @JsonProperty("isEnabled") + @Valid + public Boolean getIsEnabled() { + return isEnabled; + } + public void setIsEnabled(Boolean isEnabled) { + this.isEnabled = isEnabled; + } + + /** + **/ + public FederatedUserDefinedAuthenticator definedBy(DefinedByEnum definedBy) { + + this.definedBy = definedBy; + return this; + } + + @ApiModelProperty(value = "") + @JsonProperty("definedBy") + @Valid + public DefinedByEnum getDefinedBy() { + return definedBy; + } + public void setDefinedBy(DefinedByEnum definedBy) { + this.definedBy = definedBy; + } + + /** + **/ + public FederatedUserDefinedAuthenticator isDefault(Boolean isDefault) { + + this.isDefault = isDefault; + return this; + } + + @ApiModelProperty(value = "") + @JsonProperty("isDefault") + @Valid + public Boolean getIsDefault() { + return isDefault; + } + public void setIsDefault(Boolean isDefault) { + this.isDefault = isDefault; + } + + /** + **/ + public FederatedUserDefinedAuthenticator tags(List tags) { + + this.tags = tags; + return this; + } + + @ApiModelProperty(example = "[\"Custom\"]", value = "") + @JsonProperty("tags") + @Valid + public List getTags() { + return tags; + } + public void setTags(List tags) { + this.tags = tags; + } + + public FederatedUserDefinedAuthenticator addTagsItem(String tagsItem) { + if (this.tags == null) { + this.tags = new ArrayList<>(); + } + this.tags.add(tagsItem); + return this; + } + + /** + **/ + public FederatedUserDefinedAuthenticator endpoint(Endpoint endpoint) { + + this.endpoint = endpoint; + return this; + } + + @ApiModelProperty(value = "") + @JsonProperty("endpoint") + @Valid + public Endpoint getEndpoint() { + return endpoint; + } + public void setEndpoint(Endpoint endpoint) { + this.endpoint = endpoint; + } + + + + @Override + public boolean equals(java.lang.Object o) { + + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + FederatedUserDefinedAuthenticator federatedUserDefinedAuthenticator = (FederatedUserDefinedAuthenticator) o; + return Objects.equals(this.authenticatorId, federatedUserDefinedAuthenticator.authenticatorId) && + Objects.equals(this.name, federatedUserDefinedAuthenticator.name) && + Objects.equals(this.isEnabled, federatedUserDefinedAuthenticator.isEnabled) && + Objects.equals(this.definedBy, federatedUserDefinedAuthenticator.definedBy) && + Objects.equals(this.isDefault, federatedUserDefinedAuthenticator.isDefault) && + Objects.equals(this.tags, federatedUserDefinedAuthenticator.tags) && + Objects.equals(this.endpoint, federatedUserDefinedAuthenticator.endpoint); + } + + @Override + public int hashCode() { + return Objects.hash(authenticatorId, name, isEnabled, definedBy, isDefault, tags, endpoint); + } + + @Override + public String toString() { + + StringBuilder sb = new StringBuilder(); + sb.append("class FederatedUserDefinedAuthenticator {\n"); + + sb.append(" authenticatorId: ").append(toIndentedString(authenticatorId)).append("\n"); + sb.append(" name: ").append(toIndentedString(name)).append("\n"); + sb.append(" isEnabled: ").append(toIndentedString(isEnabled)).append("\n"); + sb.append(" definedBy: ").append(toIndentedString(definedBy)).append("\n"); + sb.append(" isDefault: ").append(toIndentedString(isDefault)).append("\n"); + sb.append(" tags: ").append(toIndentedString(tags)).append("\n"); + sb.append(" endpoint: ").append(toIndentedString(endpoint)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(java.lang.Object o) { + + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n"); + } +} + diff --git a/components/org.wso2.carbon.identity.api.server.idp/org.wso2.carbon.identity.api.server.idp.v1/src/gen/java/org/wso2/carbon/identity/api/server/idp/v1/model/FederatedUserDefinedAuthenticatorPUTRequest.java b/components/org.wso2.carbon.identity.api.server.idp/org.wso2.carbon.identity.api.server.idp.v1/src/gen/java/org/wso2/carbon/identity/api/server/idp/v1/model/FederatedUserDefinedAuthenticatorPUTRequest.java new file mode 100644 index 0000000000..5825ae4e4e --- /dev/null +++ b/components/org.wso2.carbon.identity.api.server.idp/org.wso2.carbon.identity.api.server.idp.v1/src/gen/java/org/wso2/carbon/identity/api/server/idp/v1/model/FederatedUserDefinedAuthenticatorPUTRequest.java @@ -0,0 +1,162 @@ +/* + * Copyright (c) 2024, WSO2 LLC. (http://www.wso2.com). + * + * WSO2 LLC. 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.wso2.carbon.identity.api.server.idp.v1.model; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import org.wso2.carbon.identity.api.server.idp.v1.model.Endpoint; +import javax.validation.constraints.*; + + +import io.swagger.annotations.*; +import java.util.Objects; +import javax.validation.Valid; +import javax.xml.bind.annotation.*; + +public class FederatedUserDefinedAuthenticatorPUTRequest { + + private String authenticatorId; + private Boolean isEnabled = false; + private Boolean isDefault = false; + private Endpoint endpoint; + + /** + **/ + public FederatedUserDefinedAuthenticatorPUTRequest authenticatorId(String authenticatorId) { + + this.authenticatorId = authenticatorId; + return this; + } + + @ApiModelProperty(value = "") + @JsonProperty("authenticatorId") + @Valid + public String getAuthenticatorId() { + return authenticatorId; + } + public void setAuthenticatorId(String authenticatorId) { + this.authenticatorId = authenticatorId; + } + + /** + **/ + public FederatedUserDefinedAuthenticatorPUTRequest isEnabled(Boolean isEnabled) { + + this.isEnabled = isEnabled; + return this; + } + + @ApiModelProperty(example = "true", value = "") + @JsonProperty("isEnabled") + @Valid + public Boolean getIsEnabled() { + return isEnabled; + } + public void setIsEnabled(Boolean isEnabled) { + this.isEnabled = isEnabled; + } + + /** + **/ + public FederatedUserDefinedAuthenticatorPUTRequest isDefault(Boolean isDefault) { + + this.isDefault = isDefault; + return this; + } + + @ApiModelProperty(example = "false", value = "") + @JsonProperty("isDefault") + @Valid + public Boolean getIsDefault() { + return isDefault; + } + public void setIsDefault(Boolean isDefault) { + this.isDefault = isDefault; + } + + /** + **/ + public FederatedUserDefinedAuthenticatorPUTRequest endpoint(Endpoint endpoint) { + + this.endpoint = endpoint; + return this; + } + + @ApiModelProperty(value = "") + @JsonProperty("endpoint") + @Valid + public Endpoint getEndpoint() { + return endpoint; + } + public void setEndpoint(Endpoint endpoint) { + this.endpoint = endpoint; + } + + + + @Override + public boolean equals(java.lang.Object o) { + + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + FederatedUserDefinedAuthenticatorPUTRequest federatedUserDefinedAuthenticatorPUTRequest = (FederatedUserDefinedAuthenticatorPUTRequest) o; + return Objects.equals(this.authenticatorId, federatedUserDefinedAuthenticatorPUTRequest.authenticatorId) && + Objects.equals(this.isEnabled, federatedUserDefinedAuthenticatorPUTRequest.isEnabled) && + Objects.equals(this.isDefault, federatedUserDefinedAuthenticatorPUTRequest.isDefault) && + Objects.equals(this.endpoint, federatedUserDefinedAuthenticatorPUTRequest.endpoint); + } + + @Override + public int hashCode() { + return Objects.hash(authenticatorId, isEnabled, isDefault, endpoint); + } + + @Override + public String toString() { + + StringBuilder sb = new StringBuilder(); + sb.append("class FederatedUserDefinedAuthenticatorPUTRequest {\n"); + + sb.append(" authenticatorId: ").append(toIndentedString(authenticatorId)).append("\n"); + sb.append(" isEnabled: ").append(toIndentedString(isEnabled)).append("\n"); + sb.append(" isDefault: ").append(toIndentedString(isDefault)).append("\n"); + sb.append(" endpoint: ").append(toIndentedString(endpoint)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(java.lang.Object o) { + + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n"); + } +} + diff --git a/components/org.wso2.carbon.identity.api.server.idp/org.wso2.carbon.identity.api.server.idp.v1/src/gen/java/org/wso2/carbon/identity/api/server/idp/v1/model/MetaFederatedAuthenticator.java b/components/org.wso2.carbon.identity.api.server.idp/org.wso2.carbon.identity.api.server.idp.v1/src/gen/java/org/wso2/carbon/identity/api/server/idp/v1/model/MetaFederatedAuthenticator.java index 46483c4c83..b3591fdc82 100644 --- a/components/org.wso2.carbon.identity.api.server.idp/org.wso2.carbon.identity.api.server.idp.v1/src/gen/java/org/wso2/carbon/identity/api/server/idp/v1/model/MetaFederatedAuthenticator.java +++ b/components/org.wso2.carbon.identity.api.server.idp/org.wso2.carbon.identity.api.server.idp.v1/src/gen/java/org/wso2/carbon/identity/api/server/idp/v1/model/MetaFederatedAuthenticator.java @@ -22,6 +22,7 @@ import io.swagger.annotations.ApiModelProperty; import java.util.ArrayList; import java.util.List; +import org.wso2.carbon.identity.api.server.idp.v1.model.Endpoint; import org.wso2.carbon.identity.api.server.idp.v1.model.MetaProperty; import javax.validation.constraints.*; @@ -74,6 +75,7 @@ public static DefinedByEnum fromValue(String value) { private List properties = null; + private Endpoint endpoint; /** **/ @@ -199,7 +201,25 @@ public MetaFederatedAuthenticator addPropertiesItem(MetaProperty propertiesItem) return this; } + /** + **/ + public MetaFederatedAuthenticator endpoint(Endpoint endpoint) { + + this.endpoint = endpoint; + return this; + } + @ApiModelProperty(value = "") + @JsonProperty("endpoint") + @Valid + public Endpoint getEndpoint() { + return endpoint; + } + public void setEndpoint(Endpoint endpoint) { + this.endpoint = endpoint; + } + + @Override public boolean equals(java.lang.Object o) { @@ -216,12 +236,13 @@ public boolean equals(java.lang.Object o) { Objects.equals(this.displayName, metaFederatedAuthenticator.displayName) && Objects.equals(this.definedBy, metaFederatedAuthenticator.definedBy) && Objects.equals(this.tags, metaFederatedAuthenticator.tags) && - Objects.equals(this.properties, metaFederatedAuthenticator.properties); + Objects.equals(this.properties, metaFederatedAuthenticator.properties) && + Objects.equals(this.endpoint, metaFederatedAuthenticator.endpoint); } @Override public int hashCode() { - return Objects.hash(authenticatorId, name, displayName, definedBy, tags, properties); + return Objects.hash(authenticatorId, name, displayName, definedBy, tags, properties, endpoint); } @Override @@ -236,6 +257,7 @@ public String toString() { sb.append(" definedBy: ").append(toIndentedString(definedBy)).append("\n"); sb.append(" tags: ").append(toIndentedString(tags)).append("\n"); sb.append(" properties: ").append(toIndentedString(properties)).append("\n"); + sb.append(" endpoint: ").append(toIndentedString(endpoint)).append("\n"); sb.append("}"); return sb.toString(); } diff --git a/components/org.wso2.carbon.identity.api.server.idp/org.wso2.carbon.identity.api.server.idp.v1/src/main/java/org/wso2/carbon/identity/api/server/idp/v1/core/ServerIdpManagementService.java b/components/org.wso2.carbon.identity.api.server.idp/org.wso2.carbon.identity.api.server.idp.v1/src/main/java/org/wso2/carbon/identity/api/server/idp/v1/core/ServerIdpManagementService.java index bac516e2d9..45f99e9052 100644 --- a/components/org.wso2.carbon.identity.api.server.idp/org.wso2.carbon.identity.api.server.idp.v1/src/main/java/org/wso2/carbon/identity/api/server/idp/v1/core/ServerIdpManagementService.java +++ b/components/org.wso2.carbon.identity.api.server.idp/org.wso2.carbon.identity.api.server.idp.v1/src/main/java/org/wso2/carbon/identity/api/server/idp/v1/core/ServerIdpManagementService.java @@ -34,6 +34,8 @@ import org.apache.cxf.jaxrs.ext.search.PrimitiveStatement; import org.apache.cxf.jaxrs.ext.search.SearchCondition; import org.apache.cxf.jaxrs.ext.search.SearchContext; +import org.wso2.carbon.identity.action.management.model.AuthProperty; +import org.wso2.carbon.identity.action.management.model.EndpointConfig; import org.wso2.carbon.identity.api.server.common.ContextLoader; import org.wso2.carbon.identity.api.server.common.FileContent; import org.wso2.carbon.identity.api.server.common.Util; @@ -43,11 +45,13 @@ import org.wso2.carbon.identity.api.server.idp.common.IdentityProviderServiceHolder; import org.wso2.carbon.identity.api.server.idp.v1.model.AssociationRequest; import org.wso2.carbon.identity.api.server.idp.v1.model.AssociationResponse; +import org.wso2.carbon.identity.api.server.idp.v1.model.AuthenticationType; import org.wso2.carbon.identity.api.server.idp.v1.model.Certificate; import org.wso2.carbon.identity.api.server.idp.v1.model.Claim; import org.wso2.carbon.identity.api.server.idp.v1.model.Claims; import org.wso2.carbon.identity.api.server.idp.v1.model.ConnectedApp; import org.wso2.carbon.identity.api.server.idp.v1.model.ConnectedApps; +import org.wso2.carbon.identity.api.server.idp.v1.model.Endpoint; import org.wso2.carbon.identity.api.server.idp.v1.model.FederatedAuthenticator; import org.wso2.carbon.identity.api.server.idp.v1.model.FederatedAuthenticatorListItem; import org.wso2.carbon.identity.api.server.idp.v1.model.FederatedAuthenticatorListResponse; @@ -93,6 +97,8 @@ import org.wso2.carbon.identity.application.common.model.ProvisioningConnectorConfig; import org.wso2.carbon.identity.application.common.model.RoleMapping; import org.wso2.carbon.identity.application.common.model.SubProperty; +import org.wso2.carbon.identity.application.common.model.UserDefinedAuthenticatorEndpointConfig; +import org.wso2.carbon.identity.application.common.model.UserDefinedFederatedAuthenticatorConfig; import org.wso2.carbon.identity.application.common.util.IdentityApplicationConstants; import org.wso2.carbon.identity.base.AuthenticatorPropertyConstants.DefinedByType; import org.wso2.carbon.identity.claim.metadata.mgt.exception.ClaimMetadataException; @@ -2842,17 +2848,30 @@ private FederatedAuthenticatorConfig updateFederatedAuthenticatorConfig(String f FederatedAuthenticatorPUTRequest authenticator) { - FederatedAuthenticatorConfig authConfig = new FederatedAuthenticatorConfig(); String authenticatorName = base64URLDecode(federatedAuthenticatorId); + FederatedAuthenticatorConfig authConfig; + DefinedByType definedByType = null; + if (authenticator.getDefinedBy() != null) { + definedByType = authenticator.getDefinedBy().toString(); + } + definedByType = resolveDefinedByType(authenticatorName, definedByType.toString(), false); + if (definedByType == DefinedByType.SYSTEM) { + authConfig = createSystemDefinedFederatedAuthenticator(authenticator, authenticatorName); + } else { + authConfig = createUserDefinedFederatedAuthenticator(authenticator); + } authConfig.setName(authenticatorName); authConfig.setDisplayName(getDisplayNameOfAuthenticator(authenticatorName)); authConfig.setEnabled(authenticator.getIsEnabled()); - String definedByType = null; - if (authenticator.getDefinedBy() != null) { - definedByType = authenticator.getDefinedBy().toString(); - } - authConfig.setDefinedByType(resolveDefinedByType(authenticatorName, definedByType, false)); + return authConfig; + } + + private FederatedAuthenticatorConfig createSystemDefinedFederatedAuthenticator( + FederatedAuthenticatorPUTRequest authenticator, String authenticatorName) { + + FederatedAuthenticatorConfig authConfig = new FederatedAuthenticatorConfig(); + authConfig.setDefinedByType(DefinedByType.SYSTEM); List authProperties = authenticator.getProperties(); if (IdentityApplicationConstants.Authenticator.SAML2SSO.FED_AUTH_NAME.equals(authenticatorName)) { @@ -2864,9 +2883,26 @@ private FederatedAuthenticatorConfig updateFederatedAuthenticatorConfig(String f } List properties = authProperties.stream().map(propertyToInternal).collect(Collectors.toList()); authConfig.setProperties(properties.toArray(new Property[0])); + return authConfig; } + private UserDefinedFederatedAuthenticatorConfig createUserDefinedFederatedAuthenticator( + FederatedAuthenticatorPUTRequest authenticator) { + + UserDefinedFederatedAuthenticatorConfig userDefinedAuthConfig = new UserDefinedFederatedAuthenticatorConfig(); + userDefinedAuthConfig.setDefinedByType(DefinedByType.USER); + + UserDefinedAuthenticatorEndpointConfig.UserDefinedAuthenticatorEndpointConfigBuilder endpointConfigBuilder = + new UserDefinedAuthenticatorEndpointConfig.UserDefinedAuthenticatorEndpointConfigBuilder(); + endpointConfigBuilder.uri(authenticator.getEndpoint().getUri()); + endpointConfigBuilder.authenticationType(authenticator.getEndpoint().getAuthentication().getType().toString()); + endpointConfigBuilder.authenticationProperties(authenticator.getEndpoint().getAuthentication().getProperties() + .entrySet().stream().collect(Collectors.toMap( + Map.Entry::getKey, entry -> entry.getValue().toString()))); + return userDefinedAuthConfig; + } + private DefinedByType resolveDefinedByType( String authenticatorName, String definedByType, boolean isNewFederatedAuthenticator) { @@ -3046,7 +3082,7 @@ private int getExistingAuthConfigPosition(FederatedAuthenticatorConfig[] fedAuth * @return FederatedAuthenticator. */ private FederatedAuthenticator createFederatedAuthenticator(String authenticatorId, - IdentityProvider identityProvider) { + IdentityProvider identityProvider) throws IdentityProviderManagementServerException { FederatedAuthenticatorConfig[] authConfigs = identityProvider.getFederatedAuthenticatorConfigs(); if (ArrayUtils.isEmpty(authConfigs)) { @@ -3070,8 +3106,6 @@ private FederatedAuthenticator createFederatedAuthenticator(String authenticator federatedAuthenticator.setName(config.getName()); federatedAuthenticator.setIsEnabled(config.isEnabled()); federatedAuthenticator.setIsDefault(isDefaultAuthenticator); - federatedAuthenticator.setDefinedBy(FederatedAuthenticator.DefinedByEnum.valueOf( - config.getDefinedByType().toString())); FederatedAuthenticatorConfig federatedAuthenticatorConfig = ApplicationAuthenticatorService.getInstance().getFederatedAuthenticatorByName( config.getName()); @@ -3081,13 +3115,48 @@ private FederatedAuthenticator createFederatedAuthenticator(String authenticator federatedAuthenticator.setTags(Arrays.asList(tags)); } } - List properties = - Arrays.stream(config.getProperties()).map(propertyToExternal).collect(Collectors.toList()); - federatedAuthenticator.setProperties(properties); + + if (DefinedByType.SYSTEM == config.getDefinedByType()) { + federatedAuthenticator.setDefinedBy(FederatedAuthenticator.DefinedByEnum.SYSTEM); + List properties = + Arrays.stream(config.getProperties()).map(propertyToExternal).collect(Collectors.toList()); + federatedAuthenticator.setProperties(properties); + } else { + federatedAuthenticator.setDefinedBy(FederatedAuthenticator.DefinedByEnum.USER); + resolveEndpointConfiguration(federatedAuthenticator, config); + } + } return federatedAuthenticator; } + private void resolveEndpointConfiguration(FederatedAuthenticator authenticator, + FederatedAuthenticatorConfig config) throws IdentityProviderManagementServerException { + + try { + UserDefinedFederatedAuthenticatorConfig userDefinedConfig = + (UserDefinedFederatedAuthenticatorConfig) config; + EndpointConfig endpointConfig = userDefinedConfig.getEndpointConfig().getEndpointConfig(); + + AuthenticationType authenticationType = new AuthenticationType(); + authenticationType.setType(AuthenticationType.TypeEnum.fromValue(endpointConfig + .getAuthentication().getType().toString())); + Map authenticatorProperties = new HashMap<>(); + for (AuthProperty prop: endpointConfig.getAuthentication().getProperties()) { + authenticatorProperties.put(prop.getName(), prop.getValue()); + } + authenticationType.setProperties(authenticatorProperties); + + Endpoint endpoint = new Endpoint(); + endpoint.setAuthentication(authenticationType); + endpoint.setUri(userDefinedConfig.getEndpointConfig().getEndpointConfig().getUri()); + authenticator.setEndpoint(endpoint); + } catch (ClassCastException e) { + throw new IdentityProviderManagementServerException("Error occurred while resolving endpoint " + + "configuration of the authenticator.", e); + } + } + /** * Create external OutboundConnector from Provisioning Config. * diff --git a/components/org.wso2.carbon.identity.api.server.idp/org.wso2.carbon.identity.api.server.idp.v1/src/main/resources/idp.yaml b/components/org.wso2.carbon.identity.api.server.idp/org.wso2.carbon.identity.api.server.idp.v1/src/main/resources/idp.yaml index 9e0df2e09d..53d1d0ee1b 100644 --- a/components/org.wso2.carbon.identity.api.server.idp/org.wso2.carbon.identity.api.server.idp.v1/src/main/resources/idp.yaml +++ b/components/org.wso2.carbon.identity.api.server.idp/org.wso2.carbon.identity.api.server.idp.v1/src/main/resources/idp.yaml @@ -2824,6 +2824,9 @@ components: type: array items: $ref: '#/components/schemas/MetaProperty' + endpoint: + endpoint: + $ref: '#/components/schemas/Endpoint' FederatedAuthenticatorRequest: type: object required: @@ -2877,6 +2880,37 @@ components: type: array items: $ref: '#/components/schemas/Property' + endpoint: + $ref: '#/components/schemas/Endpoint' + Endpoint: + type: object + properties: + uri: + type: string + example: https://abc.com/token + pattern: '^https?://.+' + authentication: + $ref: '#/components/schemas/AuthenticationType' + AuthenticationType: + type: object + required: + - type + - properties + properties: + type: + type: string + enum: + - NONE + - BEARER + - API_KEY + - BASIC + example: BASIC + properties: + type: object + additionalProperties: true + example: + username: "auth_username" + password: "auth_password" FederatedAuthenticatorPUTRequest: type: object properties: @@ -2905,6 +2939,8 @@ components: type: array items: $ref: '#/components/schemas/Property' + endpoint: + $ref: '#/components/schemas/Endpoint' FederatedAuthenticatorListResponse: type: object properties: From cfc2832c1a73893d4e53deb6f5c5ffcd3c884155 Mon Sep 17 00:00:00 2001 From: Thisara-Welmilla Date: Mon, 11 Nov 2024 17:14:47 +0530 Subject: [PATCH 02/10] Update APIs to support custom authentication management. --- .../api/server/idp/common/Constants.java | 12 ++ .../api/server/idp/v1/model/Endpoint.java | 10 +- .../v1/core/ServerIdpManagementService.java | 155 +++++++++++------- .../src/main/resources/idp.yaml | 4 +- 4 files changed, 119 insertions(+), 62 deletions(-) diff --git a/components/org.wso2.carbon.identity.api.server.idp/org.wso2.carbon.identity.api.server.idp.common/src/main/java/org/wso2/carbon/identity/api/server/idp/common/Constants.java b/components/org.wso2.carbon.identity.api.server.idp/org.wso2.carbon.identity.api.server.idp.common/src/main/java/org/wso2/carbon/identity/api/server/idp/common/Constants.java index 7d88182eb5..c431dfad97 100644 --- a/components/org.wso2.carbon.identity.api.server.idp/org.wso2.carbon.identity.api.server.idp.common/src/main/java/org/wso2/carbon/identity/api/server/idp/common/Constants.java +++ b/components/org.wso2.carbon.identity.api.server.idp/org.wso2.carbon.identity.api.server.idp.common/src/main/java/org/wso2/carbon/identity/api/server/idp/common/Constants.java @@ -146,6 +146,18 @@ public enum ErrorMessage { ERROR_CODE_ERROR_LISTING_TRUSTED_TOKEN_ISSUERS("60021", "Unable to list existing trusted token issuers.", "Server encountered an error while listing the trusted token issuers."), + ERROR_CODE_ENDPOINT_PROVIDED_FOR_SYSTEM_AUTH("60039", "Endpoint provided for the system " + + "defined federated authenticator", "No endpoint configuration must be provided for " + + "the system defined federated authenticators %s."), + ERROR_CODE_PROPERTIES_PROVIDED_FOR_USER_AUTH("60040", "Properties provided for the user " + + "defined federated authenticator", "No properties must be provided for the user defined " + + "federated authenticators %s."), + ERROR_CODE_NO_ENDPOINT_PROVIDED("60041", "No endpoint provided.", "Endpoint " + + "configuration must be provided for the user defined federated authenticators %s."), + ERROR_CODE_NON_DECODABLE_AUTH_ID("60042", "Non-decodable authenticator ID.", + "Unable to decode the provided authenticator ID %s."), + ERROR_CODE_NO_SYSTEM_AUTHENTICATOR_FOUND("60043", "No system authenticator found.", + "No system authenticator found for the provided authenticator Id."), // Server Error starting from 650xx. ERROR_CODE_ERROR_ADDING_IDP("65002", diff --git a/components/org.wso2.carbon.identity.api.server.idp/org.wso2.carbon.identity.api.server.idp.v1/src/gen/java/org/wso2/carbon/identity/api/server/idp/v1/model/Endpoint.java b/components/org.wso2.carbon.identity.api.server.idp/org.wso2.carbon.identity.api.server.idp.v1/src/gen/java/org/wso2/carbon/identity/api/server/idp/v1/model/Endpoint.java index 477bb8c8ad..9ce553d2ac 100644 --- a/components/org.wso2.carbon.identity.api.server.idp/org.wso2.carbon.identity.api.server.idp.v1/src/gen/java/org/wso2/carbon/identity/api/server/idp/v1/model/Endpoint.java +++ b/components/org.wso2.carbon.identity.api.server.idp/org.wso2.carbon.identity.api.server.idp.v1/src/gen/java/org/wso2/carbon/identity/api/server/idp/v1/model/Endpoint.java @@ -44,9 +44,11 @@ public Endpoint uri(String uri) { return this; } - @ApiModelProperty(example = "https://abc.com/token", value = "") + @ApiModelProperty(example = "https://abc.com/token", required = true, value = "") @JsonProperty("uri") - @Valid @Pattern(regexp="^https?://.+") + @Valid + @NotNull(message = "Property uri cannot be null.") + @Pattern(regexp="^https?://.+") public String getUri() { return uri; } @@ -62,9 +64,11 @@ public Endpoint authentication(AuthenticationType authentication) { return this; } - @ApiModelProperty(value = "") + @ApiModelProperty(required = true, value = "") @JsonProperty("authentication") @Valid + @NotNull(message = "Property authentication cannot be null.") + public AuthenticationType getAuthentication() { return authentication; } diff --git a/components/org.wso2.carbon.identity.api.server.idp/org.wso2.carbon.identity.api.server.idp.v1/src/main/java/org/wso2/carbon/identity/api/server/idp/v1/core/ServerIdpManagementService.java b/components/org.wso2.carbon.identity.api.server.idp/org.wso2.carbon.identity.api.server.idp.v1/src/main/java/org/wso2/carbon/identity/api/server/idp/v1/core/ServerIdpManagementService.java index 45f99e9052..ec4848cf03 100644 --- a/components/org.wso2.carbon.identity.api.server.idp/org.wso2.carbon.identity.api.server.idp.v1/src/main/java/org/wso2/carbon/identity/api/server/idp/v1/core/ServerIdpManagementService.java +++ b/components/org.wso2.carbon.identity.api.server.idp/org.wso2.carbon.identity.api.server.idp.v1/src/main/java/org/wso2/carbon/identity/api/server/idp/v1/core/ServerIdpManagementService.java @@ -34,8 +34,6 @@ import org.apache.cxf.jaxrs.ext.search.PrimitiveStatement; import org.apache.cxf.jaxrs.ext.search.SearchCondition; import org.apache.cxf.jaxrs.ext.search.SearchContext; -import org.wso2.carbon.identity.action.management.model.AuthProperty; -import org.wso2.carbon.identity.action.management.model.EndpointConfig; import org.wso2.carbon.identity.api.server.common.ContextLoader; import org.wso2.carbon.identity.api.server.common.FileContent; import org.wso2.carbon.identity.api.server.common.Util; @@ -1764,7 +1762,8 @@ private MetaOutboundConnector createMetaOutboundConnector(ProvisioningConnectorC } private void updateFederatedAuthenticatorConfig(IdentityProvider idp, FederatedAuthenticatorRequest - federatedAuthenticatorRequest, boolean isNewFederatedAuthenticator) { + federatedAuthenticatorRequest, boolean isNewFederatedAuthenticator) + throws IdentityProviderManagementClientException { if (federatedAuthenticatorRequest != null) { List federatedAuthenticators = federatedAuthenticatorRequest.getAuthenticators(); @@ -1772,34 +1771,43 @@ private void updateFederatedAuthenticatorConfig(IdentityProvider idp, FederatedA FederatedAuthenticatorConfig defaultAuthConfig = null; List fedAuthConfigs = new ArrayList<>(); for (FederatedAuthenticator authenticator : federatedAuthenticators) { - FederatedAuthenticatorConfig authConfig = new FederatedAuthenticatorConfig(); - authConfig.setName(base64URLDecode(authenticator.getAuthenticatorId())); - authConfig.setDisplayName(getDisplayNameOfAuthenticator(authConfig.getName())); - authConfig.setEnabled(authenticator.getIsEnabled()); - + String authenticatorName = getDecodedAuthName(authenticator.getAuthenticatorId()); + FederatedAuthenticatorConfig authConfig; String definedByType = null; if (authenticator.getDefinedBy() != null) { definedByType = authenticator.getDefinedBy().toString(); } - authConfig.setDefinedByType(resolveDefinedByType(authConfig.getName(), - definedByType, isNewFederatedAuthenticator)); - List authProperties = - authenticator.getProperties(); - if (IdentityApplicationConstants.Authenticator.SAML2SSO.FED_AUTH_NAME.equals(authConfig.getName())) { - validateSamlMetadata(authProperties); - } - if (authProperties != null) { - if (!areAllDistinct(authProperties)) { - throw handleException(Response.Status.BAD_REQUEST, - Constants.ErrorMessage.ERROR_CODE_INVALID_INPUT, " Duplicate properties are found in " + - "the request."); + definedByType = resolveDefinedByType(authenticatorName, definedByType, isNewFederatedAuthenticator) + .toString(); + if (DefinedByType.SYSTEM.toString().equals(definedByType)) { + authConfig = createSystemDefinedFederatedAuthenticator(authenticatorName, + authenticator.getEndpoint()); + List authProperties = + authenticator.getProperties(); + if (IdentityApplicationConstants.Authenticator.SAML2SSO.FED_AUTH_NAME + .equals(authConfig.getName())) { + validateSamlMetadata(authProperties); } - List properties = authProperties.stream() - .map(propertyToInternal) - .collect(Collectors.toList()); - authConfig.setProperties(properties.toArray(new Property[0])); + if (authProperties != null) { + if (!areAllDistinct(authProperties)) { + throw handleException(Response.Status.BAD_REQUEST, + Constants.ErrorMessage.ERROR_CODE_INVALID_INPUT, " Duplicate properties are found" + + " in the request."); + } + List properties = authProperties.stream() + .map(propertyToInternal) + .collect(Collectors.toList()); + authConfig.setProperties(properties.toArray(new Property[0])); + } + } else { + authConfig = createUserDefinedFederatedAuthenticator(authenticatorName, authenticator.getEndpoint(), + authenticator.getProperties()); } + + authConfig.setName(authenticatorName); + authConfig.setDisplayName(getDisplayNameOfAuthenticator(authConfig.getName())); + authConfig.setEnabled(authenticator.getIsEnabled()); fedAuthConfigs.add(authConfig); if (StringUtils.equals(defaultAuthenticator, authenticator.getAuthenticatorId())) { @@ -2085,7 +2093,8 @@ private void updateGroups(IdentityProvider idp, List groups) { return apiProperty; }; - private IdentityProvider createIDP(IdentityProviderPOSTRequest identityProviderPOSTRequest) { + private IdentityProvider createIDP(IdentityProviderPOSTRequest identityProviderPOSTRequest) + throws IdentityProviderManagementClientException { String idpJWKSUri = null; IdentityProvider idp = new IdentityProvider(); @@ -2845,20 +2854,30 @@ private ProvisioningConnectorConfig createProvisioningConnectorConfig(String out * @return Federated authenticator config of the specified ID. */ private FederatedAuthenticatorConfig updateFederatedAuthenticatorConfig(String federatedAuthenticatorId, - FederatedAuthenticatorPUTRequest - authenticator) { + FederatedAuthenticatorPUTRequest authenticator) throws IdentityProviderManagementClientException { - String authenticatorName = base64URLDecode(federatedAuthenticatorId); + String authenticatorName = getDecodedAuthName(federatedAuthenticatorId); FederatedAuthenticatorConfig authConfig; - DefinedByType definedByType = null; + String definedByType = null; if (authenticator.getDefinedBy() != null) { definedByType = authenticator.getDefinedBy().toString(); } - definedByType = resolveDefinedByType(authenticatorName, definedByType.toString(), false); - if (definedByType == DefinedByType.SYSTEM) { - authConfig = createSystemDefinedFederatedAuthenticator(authenticator, authenticatorName); + definedByType = resolveDefinedByType(authenticatorName, definedByType, false).toString(); + if (DefinedByType.SYSTEM.toString().equals(definedByType)) { + authConfig = createSystemDefinedFederatedAuthenticator(authenticatorName, authenticator.getEndpoint()); + if (IdentityApplicationConstants.Authenticator.SAML2SSO.FED_AUTH_NAME.equals(authenticatorName)) { + validateSamlMetadata(authenticator.getProperties()); + } + if (IdentityApplicationConstants.Authenticator.OIDC.FED_AUTH_NAME.equals(authenticatorName)) { + validateDuplicateOpenIDConnectScopes(authenticator.getProperties()); + validateDefaultOpenIDConnectScopes(authenticator.getProperties()); + } + List properties = authenticator.getProperties().stream().map(propertyToInternal) + .collect(Collectors.toList()); + authConfig.setProperties(properties.toArray(new Property[0])); } else { - authConfig = createUserDefinedFederatedAuthenticator(authenticator); + authConfig = createUserDefinedFederatedAuthenticator(authenticatorName, authenticator.getEndpoint(), + authenticator.getProperties()); } authConfig.setName(authenticatorName); authConfig.setDisplayName(getDisplayNameOfAuthenticator(authenticatorName)); @@ -2868,38 +2887,53 @@ private FederatedAuthenticatorConfig updateFederatedAuthenticatorConfig(String f } private FederatedAuthenticatorConfig createSystemDefinedFederatedAuthenticator( - FederatedAuthenticatorPUTRequest authenticator, String authenticatorName) { + String authenticatorName, Endpoint endpoint) throws IdentityProviderManagementClientException { - FederatedAuthenticatorConfig authConfig = new FederatedAuthenticatorConfig(); - authConfig.setDefinedByType(DefinedByType.SYSTEM); - - List authProperties = authenticator.getProperties(); - if (IdentityApplicationConstants.Authenticator.SAML2SSO.FED_AUTH_NAME.equals(authenticatorName)) { - validateSamlMetadata(authProperties); + if (endpoint != null) { + Constants.ErrorMessage error = Constants.ErrorMessage.ERROR_CODE_ENDPOINT_PROVIDED_FOR_SYSTEM_AUTH; + throw new IdentityProviderManagementClientException(error.getCode(), + String.format(error.getDescription(), authenticatorName)); } - if (IdentityApplicationConstants.Authenticator.OIDC.FED_AUTH_NAME.equals(authenticatorName)) { - validateDuplicateOpenIDConnectScopes(authProperties); - validateDefaultOpenIDConnectScopes(authProperties); + + if (ApplicationAuthenticatorService.getInstance() + .getFederatedAuthenticatorByName((authenticatorName)) == null) { + Constants.ErrorMessage error = Constants.ErrorMessage.ERROR_CODE_NO_SYSTEM_AUTHENTICATOR_FOUND; + throw new IdentityProviderManagementClientException(error.getCode(), error.getDescription()); } - List properties = authProperties.stream().map(propertyToInternal).collect(Collectors.toList()); - authConfig.setProperties(properties.toArray(new Property[0])); + + FederatedAuthenticatorConfig authConfig = new FederatedAuthenticatorConfig(); + authConfig.setDefinedByType(DefinedByType.SYSTEM); return authConfig; } private UserDefinedFederatedAuthenticatorConfig createUserDefinedFederatedAuthenticator( - FederatedAuthenticatorPUTRequest authenticator) { + String authenticatorName, Endpoint endpoint, List + properties) throws IdentityProviderManagementClientException { + + if (properties == null || !properties.isEmpty()) { + Constants.ErrorMessage error = Constants.ErrorMessage.ERROR_CODE_PROPERTIES_PROVIDED_FOR_USER_AUTH; + throw new IdentityProviderManagementClientException(error.getCode(), + String.format(error.getDescription(), authenticatorName)); + } + + if (endpoint == null || endpoint.getUri() == null || endpoint.getAuthentication() == null) { + Constants.ErrorMessage error = Constants.ErrorMessage.ERROR_CODE_NO_ENDPOINT_PROVIDED; + throw new IdentityProviderManagementClientException(error.getCode(), + String.format(error.getDescription(), authenticatorName)); + } UserDefinedFederatedAuthenticatorConfig userDefinedAuthConfig = new UserDefinedFederatedAuthenticatorConfig(); userDefinedAuthConfig.setDefinedByType(DefinedByType.USER); UserDefinedAuthenticatorEndpointConfig.UserDefinedAuthenticatorEndpointConfigBuilder endpointConfigBuilder = new UserDefinedAuthenticatorEndpointConfig.UserDefinedAuthenticatorEndpointConfigBuilder(); - endpointConfigBuilder.uri(authenticator.getEndpoint().getUri()); - endpointConfigBuilder.authenticationType(authenticator.getEndpoint().getAuthentication().getType().toString()); - endpointConfigBuilder.authenticationProperties(authenticator.getEndpoint().getAuthentication().getProperties() + endpointConfigBuilder.uri(endpoint.getUri()); + endpointConfigBuilder.authenticationType(endpoint.getAuthentication().getType().toString()); + endpointConfigBuilder.authenticationProperties(endpoint.getAuthentication().getProperties() .entrySet().stream().collect(Collectors.toMap( Map.Entry::getKey, entry -> entry.getValue().toString()))); + userDefinedAuthConfig.setEndpointConfig(endpointConfigBuilder.build()); return userDefinedAuthConfig; } @@ -3136,20 +3170,14 @@ private void resolveEndpointConfiguration(FederatedAuthenticator authenticator, try { UserDefinedFederatedAuthenticatorConfig userDefinedConfig = (UserDefinedFederatedAuthenticatorConfig) config; - EndpointConfig endpointConfig = userDefinedConfig.getEndpointConfig().getEndpointConfig(); + UserDefinedAuthenticatorEndpointConfig endpointConfig = userDefinedConfig.getEndpointConfig(); AuthenticationType authenticationType = new AuthenticationType(); - authenticationType.setType(AuthenticationType.TypeEnum.fromValue(endpointConfig + authenticationType.setType(AuthenticationType.TypeEnum.fromValue(endpointConfig.getEndpointConfig() .getAuthentication().getType().toString())); - Map authenticatorProperties = new HashMap<>(); - for (AuthProperty prop: endpointConfig.getAuthentication().getProperties()) { - authenticatorProperties.put(prop.getName(), prop.getValue()); - } - authenticationType.setProperties(authenticatorProperties); Endpoint endpoint = new Endpoint(); - endpoint.setAuthentication(authenticationType); - endpoint.setUri(userDefinedConfig.getEndpointConfig().getEndpointConfig().getUri()); + endpoint.setUri(endpointConfig.getEndpointConfig().getUri()); authenticator.setEndpoint(endpoint); } catch (ClassCastException e) { throw new IdentityProviderManagementServerException("Error occurred while resolving endpoint " + @@ -3924,4 +3952,15 @@ private void validateSystemReservedIDP(String idpName) throws IdentityProviderMa "a system reserved name.", idpName)); } } + + private String getDecodedAuthName(String authId) throws IdentityProviderManagementClientException { + + try { + return base64URLDecode(authId); + } catch (IllegalArgumentException e) { + Constants.ErrorMessage error = Constants.ErrorMessage.ERROR_CODE_NON_DECODABLE_AUTH_ID; + throw new IdentityProviderManagementClientException(error.getCode(), + String.format(error.getDescription(), authId)); + } + } } diff --git a/components/org.wso2.carbon.identity.api.server.idp/org.wso2.carbon.identity.api.server.idp.v1/src/main/resources/idp.yaml b/components/org.wso2.carbon.identity.api.server.idp/org.wso2.carbon.identity.api.server.idp.v1/src/main/resources/idp.yaml index 53d1d0ee1b..875aa8ad8c 100644 --- a/components/org.wso2.carbon.identity.api.server.idp/org.wso2.carbon.identity.api.server.idp.v1/src/main/resources/idp.yaml +++ b/components/org.wso2.carbon.identity.api.server.idp/org.wso2.carbon.identity.api.server.idp.v1/src/main/resources/idp.yaml @@ -2825,7 +2825,6 @@ components: items: $ref: '#/components/schemas/MetaProperty' endpoint: - endpoint: $ref: '#/components/schemas/Endpoint' FederatedAuthenticatorRequest: type: object @@ -2884,6 +2883,9 @@ components: $ref: '#/components/schemas/Endpoint' Endpoint: type: object + required: + - uri + - authentication properties: uri: type: string From 88ce34f918e1651488707cce0b86be7e1f30357f Mon Sep 17 00:00:00 2001 From: Thisara-Welmilla Date: Tue, 12 Nov 2024 10:21:47 +0530 Subject: [PATCH 03/10] Update APIs to support custom authentication management. --- .../v1/model/MetaFederatedAuthenticator.java | 26 ++----------------- .../v1/core/ServerIdpManagementService.java | 2 ++ .../src/main/resources/idp.yaml | 2 -- 3 files changed, 4 insertions(+), 26 deletions(-) diff --git a/components/org.wso2.carbon.identity.api.server.idp/org.wso2.carbon.identity.api.server.idp.v1/src/gen/java/org/wso2/carbon/identity/api/server/idp/v1/model/MetaFederatedAuthenticator.java b/components/org.wso2.carbon.identity.api.server.idp/org.wso2.carbon.identity.api.server.idp.v1/src/gen/java/org/wso2/carbon/identity/api/server/idp/v1/model/MetaFederatedAuthenticator.java index b3591fdc82..46483c4c83 100644 --- a/components/org.wso2.carbon.identity.api.server.idp/org.wso2.carbon.identity.api.server.idp.v1/src/gen/java/org/wso2/carbon/identity/api/server/idp/v1/model/MetaFederatedAuthenticator.java +++ b/components/org.wso2.carbon.identity.api.server.idp/org.wso2.carbon.identity.api.server.idp.v1/src/gen/java/org/wso2/carbon/identity/api/server/idp/v1/model/MetaFederatedAuthenticator.java @@ -22,7 +22,6 @@ import io.swagger.annotations.ApiModelProperty; import java.util.ArrayList; import java.util.List; -import org.wso2.carbon.identity.api.server.idp.v1.model.Endpoint; import org.wso2.carbon.identity.api.server.idp.v1.model.MetaProperty; import javax.validation.constraints.*; @@ -75,7 +74,6 @@ public static DefinedByEnum fromValue(String value) { private List properties = null; - private Endpoint endpoint; /** **/ @@ -201,25 +199,7 @@ public MetaFederatedAuthenticator addPropertiesItem(MetaProperty propertiesItem) return this; } - /** - **/ - public MetaFederatedAuthenticator endpoint(Endpoint endpoint) { - - this.endpoint = endpoint; - return this; - } - @ApiModelProperty(value = "") - @JsonProperty("endpoint") - @Valid - public Endpoint getEndpoint() { - return endpoint; - } - public void setEndpoint(Endpoint endpoint) { - this.endpoint = endpoint; - } - - @Override public boolean equals(java.lang.Object o) { @@ -236,13 +216,12 @@ public boolean equals(java.lang.Object o) { Objects.equals(this.displayName, metaFederatedAuthenticator.displayName) && Objects.equals(this.definedBy, metaFederatedAuthenticator.definedBy) && Objects.equals(this.tags, metaFederatedAuthenticator.tags) && - Objects.equals(this.properties, metaFederatedAuthenticator.properties) && - Objects.equals(this.endpoint, metaFederatedAuthenticator.endpoint); + Objects.equals(this.properties, metaFederatedAuthenticator.properties); } @Override public int hashCode() { - return Objects.hash(authenticatorId, name, displayName, definedBy, tags, properties, endpoint); + return Objects.hash(authenticatorId, name, displayName, definedBy, tags, properties); } @Override @@ -257,7 +236,6 @@ public String toString() { sb.append(" definedBy: ").append(toIndentedString(definedBy)).append("\n"); sb.append(" tags: ").append(toIndentedString(tags)).append("\n"); sb.append(" properties: ").append(toIndentedString(properties)).append("\n"); - sb.append(" endpoint: ").append(toIndentedString(endpoint)).append("\n"); sb.append("}"); return sb.toString(); } diff --git a/components/org.wso2.carbon.identity.api.server.idp/org.wso2.carbon.identity.api.server.idp.v1/src/main/java/org/wso2/carbon/identity/api/server/idp/v1/core/ServerIdpManagementService.java b/components/org.wso2.carbon.identity.api.server.idp/org.wso2.carbon.identity.api.server.idp.v1/src/main/java/org/wso2/carbon/identity/api/server/idp/v1/core/ServerIdpManagementService.java index ec4848cf03..1e9b62d92a 100644 --- a/components/org.wso2.carbon.identity.api.server.idp/org.wso2.carbon.identity.api.server.idp.v1/src/main/java/org/wso2/carbon/identity/api/server/idp/v1/core/ServerIdpManagementService.java +++ b/components/org.wso2.carbon.identity.api.server.idp/org.wso2.carbon.identity.api.server.idp.v1/src/main/java/org/wso2/carbon/identity/api/server/idp/v1/core/ServerIdpManagementService.java @@ -1699,6 +1699,7 @@ private MetaFederatedAuthenticatorListItem createMetaFederatedAuthenticatorListI String authenticatorId = base64URLEncode(authenticatorConfig.getName()); metaFederatedAuthenticator.setName(authenticatorConfig.getName()); metaFederatedAuthenticator.setAuthenticatorId(authenticatorId); + metaFederatedAuthenticator.setDefinedBy(MetaFederatedAuthenticatorListItem.DefinedByEnum.SYSTEM); FederatedAuthenticatorConfig federatedAuthenticatorConfig = ApplicationAuthenticatorService.getInstance() .getFederatedAuthenticatorByName(authenticatorConfig.getName()); if (federatedAuthenticatorConfig != null) { @@ -1727,6 +1728,7 @@ private MetaFederatedAuthenticator createMetaFederatedAuthenticator(FederatedAut metaFederatedAuthenticator.setTags(Arrays.asList(tags)); } } + metaFederatedAuthenticator.setDefinedBy(MetaFederatedAuthenticator.DefinedByEnum.SYSTEM); Property[] properties = authenticatorConfig.getProperties(); List metaProperties = Arrays.stream(properties).map(propertyToExternalMeta).collect(Collectors .toList()); diff --git a/components/org.wso2.carbon.identity.api.server.idp/org.wso2.carbon.identity.api.server.idp.v1/src/main/resources/idp.yaml b/components/org.wso2.carbon.identity.api.server.idp/org.wso2.carbon.identity.api.server.idp.v1/src/main/resources/idp.yaml index 875aa8ad8c..1e62cdb2d8 100644 --- a/components/org.wso2.carbon.identity.api.server.idp/org.wso2.carbon.identity.api.server.idp.v1/src/main/resources/idp.yaml +++ b/components/org.wso2.carbon.identity.api.server.idp/org.wso2.carbon.identity.api.server.idp.v1/src/main/resources/idp.yaml @@ -2824,8 +2824,6 @@ components: type: array items: $ref: '#/components/schemas/MetaProperty' - endpoint: - $ref: '#/components/schemas/Endpoint' FederatedAuthenticatorRequest: type: object required: From 6d3a143e273b485546fd25255aa23b4f61c028fd Mon Sep 17 00:00:00 2001 From: Thisara-Welmilla Date: Tue, 12 Nov 2024 12:57:50 +0530 Subject: [PATCH 04/10] Update APIs to support custom authentication management. --- .../api/server/idp/common/Constants.java | 12 +- .../v1/core/ServerIdpManagementService.java | 180 ++++++------------ ...atedAuthenticatorConfigBuilderFactory.java | 175 +++++++++++++++++ 3 files changed, 244 insertions(+), 123 deletions(-) create mode 100644 components/org.wso2.carbon.identity.api.server.idp/org.wso2.carbon.identity.api.server.idp.v1/src/main/java/org/wso2/carbon/identity/api/server/idp/v1/impl/FederatedAuthenticatorConfigBuilderFactory.java diff --git a/components/org.wso2.carbon.identity.api.server.idp/org.wso2.carbon.identity.api.server.idp.common/src/main/java/org/wso2/carbon/identity/api/server/idp/common/Constants.java b/components/org.wso2.carbon.identity.api.server.idp/org.wso2.carbon.identity.api.server.idp.common/src/main/java/org/wso2/carbon/identity/api/server/idp/common/Constants.java index c431dfad97..7b96242696 100644 --- a/components/org.wso2.carbon.identity.api.server.idp/org.wso2.carbon.identity.api.server.idp.common/src/main/java/org/wso2/carbon/identity/api/server/idp/common/Constants.java +++ b/components/org.wso2.carbon.identity.api.server.idp/org.wso2.carbon.identity.api.server.idp.common/src/main/java/org/wso2/carbon/identity/api/server/idp/common/Constants.java @@ -146,18 +146,18 @@ public enum ErrorMessage { ERROR_CODE_ERROR_LISTING_TRUSTED_TOKEN_ISSUERS("60021", "Unable to list existing trusted token issuers.", "Server encountered an error while listing the trusted token issuers."), - ERROR_CODE_ENDPOINT_PROVIDED_FOR_SYSTEM_AUTH("60039", "Endpoint provided for the system " + - "defined federated authenticator", "No endpoint configuration must be provided for " + - "the system defined federated authenticators %s."), - ERROR_CODE_PROPERTIES_PROVIDED_FOR_USER_AUTH("60040", "Properties provided for the user " + - "defined federated authenticator", "No properties must be provided for the user defined " + + ERROR_CODE_ENDPOINT_PROVIDED_FOR_SYSTEM_AUTH("60039", "No endpoint configuration is allowed " + + "for system defined authenticators.", "No endpoint configuration must be " + + "provided for the system defined federated authenticators %s."), + ERROR_CODE_PROPERTIES_PROVIDED_FOR_USER_AUTH("60040", "No properties are allowed for " + + "user defined authenticators.", "No properties must be provided for the user defined " + "federated authenticators %s."), ERROR_CODE_NO_ENDPOINT_PROVIDED("60041", "No endpoint provided.", "Endpoint " + "configuration must be provided for the user defined federated authenticators %s."), ERROR_CODE_NON_DECODABLE_AUTH_ID("60042", "Non-decodable authenticator ID.", "Unable to decode the provided authenticator ID %s."), ERROR_CODE_NO_SYSTEM_AUTHENTICATOR_FOUND("60043", "No system authenticator found.", - "No system authenticator found for the provided authenticator Id."), + "No system authenticator found for the provided authenticator Id %s."), // Server Error starting from 650xx. ERROR_CODE_ERROR_ADDING_IDP("65002", diff --git a/components/org.wso2.carbon.identity.api.server.idp/org.wso2.carbon.identity.api.server.idp.v1/src/main/java/org/wso2/carbon/identity/api/server/idp/v1/core/ServerIdpManagementService.java b/components/org.wso2.carbon.identity.api.server.idp/org.wso2.carbon.identity.api.server.idp.v1/src/main/java/org/wso2/carbon/identity/api/server/idp/v1/core/ServerIdpManagementService.java index 1e9b62d92a..34602068d7 100644 --- a/components/org.wso2.carbon.identity.api.server.idp/org.wso2.carbon.identity.api.server.idp.v1/src/main/java/org/wso2/carbon/identity/api/server/idp/v1/core/ServerIdpManagementService.java +++ b/components/org.wso2.carbon.identity.api.server.idp/org.wso2.carbon.identity.api.server.idp.v1/src/main/java/org/wso2/carbon/identity/api/server/idp/v1/core/ServerIdpManagementService.java @@ -41,6 +41,7 @@ import org.wso2.carbon.identity.api.server.common.error.ErrorResponse; import org.wso2.carbon.identity.api.server.idp.common.Constants; import org.wso2.carbon.identity.api.server.idp.common.IdentityProviderServiceHolder; +import org.wso2.carbon.identity.api.server.idp.v1.impl.FederatedAuthenticatorConfigBuilderFactory; import org.wso2.carbon.identity.api.server.idp.v1.model.AssociationRequest; import org.wso2.carbon.identity.api.server.idp.v1.model.AssociationResponse; import org.wso2.carbon.identity.api.server.idp.v1.model.AuthenticationType; @@ -1773,43 +1774,31 @@ private void updateFederatedAuthenticatorConfig(IdentityProvider idp, FederatedA FederatedAuthenticatorConfig defaultAuthConfig = null; List fedAuthConfigs = new ArrayList<>(); for (FederatedAuthenticator authenticator : federatedAuthenticators) { - String authenticatorName = getDecodedAuthName(authenticator.getAuthenticatorId()); - FederatedAuthenticatorConfig authConfig; - String definedByType = null; - if (authenticator.getDefinedBy() != null) { - definedByType = authenticator.getDefinedBy().toString(); + String authenticatorName = getDecodedAuthenticatorName(authenticator.getAuthenticatorId()); + String definedByType; + if (isNewFederatedAuthenticator) { + definedByType = resolveDefinedByTypeForCreateFederatedAuthenticator( + authenticator.getDefinedBy().toString()).toString(); + } else { + definedByType = resolveDefinedByTypeForUpdateFederatedAuthenticator(authenticatorName).toString(); } - definedByType = resolveDefinedByType(authenticatorName, definedByType, isNewFederatedAuthenticator) - .toString(); if (DefinedByType.SYSTEM.toString().equals(definedByType)) { - authConfig = createSystemDefinedFederatedAuthenticator(authenticatorName, - authenticator.getEndpoint()); - List authProperties = - authenticator.getProperties(); - if (IdentityApplicationConstants.Authenticator.SAML2SSO.FED_AUTH_NAME - .equals(authConfig.getName())) { - validateSamlMetadata(authProperties); - } - if (authProperties != null) { - if (!areAllDistinct(authProperties)) { - throw handleException(Response.Status.BAD_REQUEST, - Constants.ErrorMessage.ERROR_CODE_INVALID_INPUT, " Duplicate properties are found" + - " in the request."); - } - List properties = authProperties.stream() - .map(propertyToInternal) - .collect(Collectors.toList()); - authConfig.setProperties(properties.toArray(new Property[0])); - } - } else { - authConfig = createUserDefinedFederatedAuthenticator(authenticatorName, authenticator.getEndpoint(), - authenticator.getProperties()); + validateAuthenticatorProperties(authenticatorName, authenticator.getProperties()); } - authConfig.setName(authenticatorName); - authConfig.setDisplayName(getDisplayNameOfAuthenticator(authConfig.getName())); - authConfig.setEnabled(authenticator.getIsEnabled()); + FederatedAuthenticatorConfigBuilderFactory.Builder builder = + new FederatedAuthenticatorConfigBuilderFactory.Builder(); + builder.authenticatorName(authenticatorName); + builder.definedByType(definedByType); + builder.enabled(authenticator.getIsEnabled()); + builder.displayName(getDisplayNameOfAuthenticator(authenticatorName)); + builder.endpoint(authenticator.getEndpoint()); + List properties = authenticator.getProperties().stream().map(propertyToInternal) + .collect(Collectors.toList()); + builder.properties(properties); + FederatedAuthenticatorConfig authConfig = builder.build(); + fedAuthConfigs.add(authConfig); if (StringUtils.equals(defaultAuthenticator, authenticator.getAuthenticatorId())) { @@ -2858,99 +2847,38 @@ private ProvisioningConnectorConfig createProvisioningConnectorConfig(String out private FederatedAuthenticatorConfig updateFederatedAuthenticatorConfig(String federatedAuthenticatorId, FederatedAuthenticatorPUTRequest authenticator) throws IdentityProviderManagementClientException { - String authenticatorName = getDecodedAuthName(federatedAuthenticatorId); - FederatedAuthenticatorConfig authConfig; - String definedByType = null; - if (authenticator.getDefinedBy() != null) { - definedByType = authenticator.getDefinedBy().toString(); - } - definedByType = resolveDefinedByType(authenticatorName, definedByType, false).toString(); + String authenticatorName = getDecodedAuthenticatorName(federatedAuthenticatorId); + String definedByType = resolveDefinedByTypeForUpdateFederatedAuthenticator(authenticatorName).toString(); if (DefinedByType.SYSTEM.toString().equals(definedByType)) { - authConfig = createSystemDefinedFederatedAuthenticator(authenticatorName, authenticator.getEndpoint()); - if (IdentityApplicationConstants.Authenticator.SAML2SSO.FED_AUTH_NAME.equals(authenticatorName)) { - validateSamlMetadata(authenticator.getProperties()); - } - if (IdentityApplicationConstants.Authenticator.OIDC.FED_AUTH_NAME.equals(authenticatorName)) { - validateDuplicateOpenIDConnectScopes(authenticator.getProperties()); - validateDefaultOpenIDConnectScopes(authenticator.getProperties()); - } - List properties = authenticator.getProperties().stream().map(propertyToInternal) - .collect(Collectors.toList()); - authConfig.setProperties(properties.toArray(new Property[0])); - } else { - authConfig = createUserDefinedFederatedAuthenticator(authenticatorName, authenticator.getEndpoint(), - authenticator.getProperties()); + validateAuthenticatorProperties(authenticatorName, authenticator.getProperties()); } - authConfig.setName(authenticatorName); - authConfig.setDisplayName(getDisplayNameOfAuthenticator(authenticatorName)); - authConfig.setEnabled(authenticator.getIsEnabled()); - return authConfig; - } - - private FederatedAuthenticatorConfig createSystemDefinedFederatedAuthenticator( - String authenticatorName, Endpoint endpoint) throws IdentityProviderManagementClientException { - - if (endpoint != null) { - Constants.ErrorMessage error = Constants.ErrorMessage.ERROR_CODE_ENDPOINT_PROVIDED_FOR_SYSTEM_AUTH; - throw new IdentityProviderManagementClientException(error.getCode(), - String.format(error.getDescription(), authenticatorName)); - } - - if (ApplicationAuthenticatorService.getInstance() - .getFederatedAuthenticatorByName((authenticatorName)) == null) { - Constants.ErrorMessage error = Constants.ErrorMessage.ERROR_CODE_NO_SYSTEM_AUTHENTICATOR_FOUND; - throw new IdentityProviderManagementClientException(error.getCode(), error.getDescription()); - } - - FederatedAuthenticatorConfig authConfig = new FederatedAuthenticatorConfig(); - authConfig.setDefinedByType(DefinedByType.SYSTEM); + FederatedAuthenticatorConfigBuilderFactory.Builder builder = new FederatedAuthenticatorConfigBuilderFactory + .Builder(); + builder.authenticatorName(authenticatorName); + builder.definedByType(definedByType); + builder.enabled(authenticator.getIsEnabled()); + builder.displayName(getDisplayNameOfAuthenticator(authenticatorName)); + builder.endpoint(authenticator.getEndpoint()); + List properties = authenticator.getProperties().stream().map(propertyToInternal) + .collect(Collectors.toList()); + builder.properties(properties); - return authConfig; + return builder.build(); } - private UserDefinedFederatedAuthenticatorConfig createUserDefinedFederatedAuthenticator( - String authenticatorName, Endpoint endpoint, List - properties) throws IdentityProviderManagementClientException { + private DefinedByType resolveDefinedByTypeForCreateFederatedAuthenticator(String definedByType) { - if (properties == null || !properties.isEmpty()) { - Constants.ErrorMessage error = Constants.ErrorMessage.ERROR_CODE_PROPERTIES_PROVIDED_FOR_USER_AUTH; - throw new IdentityProviderManagementClientException(error.getCode(), - String.format(error.getDescription(), authenticatorName)); - } - - if (endpoint == null || endpoint.getUri() == null || endpoint.getAuthentication() == null) { - Constants.ErrorMessage error = Constants.ErrorMessage.ERROR_CODE_NO_ENDPOINT_PROVIDED; - throw new IdentityProviderManagementClientException(error.getCode(), - String.format(error.getDescription(), authenticatorName)); + /* For new federated authenticators: + If 'definedByType' is not null, use the value provided in the request payload. If not, default to SYSTEM. */ + if (definedByType != null) { + return DefinedByType.valueOf(definedByType); } - - UserDefinedFederatedAuthenticatorConfig userDefinedAuthConfig = new UserDefinedFederatedAuthenticatorConfig(); - userDefinedAuthConfig.setDefinedByType(DefinedByType.USER); - - UserDefinedAuthenticatorEndpointConfig.UserDefinedAuthenticatorEndpointConfigBuilder endpointConfigBuilder = - new UserDefinedAuthenticatorEndpointConfig.UserDefinedAuthenticatorEndpointConfigBuilder(); - endpointConfigBuilder.uri(endpoint.getUri()); - endpointConfigBuilder.authenticationType(endpoint.getAuthentication().getType().toString()); - endpointConfigBuilder.authenticationProperties(endpoint.getAuthentication().getProperties() - .entrySet().stream().collect(Collectors.toMap( - Map.Entry::getKey, entry -> entry.getValue().toString()))); - userDefinedAuthConfig.setEndpointConfig(endpointConfigBuilder.build()); - return userDefinedAuthConfig; + return DefinedByType.SYSTEM; } - private DefinedByType resolveDefinedByType( - String authenticatorName, String definedByType, boolean isNewFederatedAuthenticator) { + private DefinedByType resolveDefinedByTypeForUpdateFederatedAuthenticator(String authenticatorName) { - /* For new federated authenticators: - If 'definedByType' is not null, use the value provided in the request payload. If not, default to SYSTEM. */ - if (isNewFederatedAuthenticator) { - if (definedByType != null) { - return DefinedByType.valueOf(definedByType); - } else { - return DefinedByType.SYSTEM; - } - } /* For existing federated authenticators, disregard any value provided in the request payload. Instead, resolve and retrieve the 'definedBy' type of the corresponding existing authenticator. If the authenticator config is present in the ApplicationAuthenticatorService list, return its type, @@ -3182,8 +3110,8 @@ private void resolveEndpointConfiguration(FederatedAuthenticator authenticator, endpoint.setUri(endpointConfig.getEndpointConfig().getUri()); authenticator.setEndpoint(endpoint); } catch (ClassCastException e) { - throw new IdentityProviderManagementServerException("Error occurred while resolving endpoint " + - "configuration of the authenticator.", e); + throw new IdentityProviderManagementServerException(String.format("Error occurred while resolving" + + " endpoint configuration of the authenticator %s.", authenticator.getName()), e); } } @@ -3955,7 +3883,7 @@ private void validateSystemReservedIDP(String idpName) throws IdentityProviderMa } } - private String getDecodedAuthName(String authId) throws IdentityProviderManagementClientException { + private String getDecodedAuthenticatorName(String authId) throws IdentityProviderManagementClientException { try { return base64URLDecode(authId); @@ -3965,4 +3893,22 @@ private String getDecodedAuthName(String authId) throws IdentityProviderManageme String.format(error.getDescription(), authId)); } } + + private void validateAuthenticatorProperties(String authenticatorName, + List properties) + throws IdentityProviderManagementClientException { + + if (IdentityApplicationConstants.Authenticator.SAML2SSO.FED_AUTH_NAME.equals(authenticatorName)) { + validateSamlMetadata(properties); + } + if (IdentityApplicationConstants.Authenticator.OIDC.FED_AUTH_NAME.equals(authenticatorName)) { + validateDuplicateOpenIDConnectScopes(properties); + validateDefaultOpenIDConnectScopes(properties); + } + + if (!areAllDistinct(properties)) { + Constants.ErrorMessage error = Constants.ErrorMessage.ERROR_CODE_INVALID_INPUT; + throw new IdentityProviderManagementClientException(error.getCode(), error.getDescription()); + } + } } diff --git a/components/org.wso2.carbon.identity.api.server.idp/org.wso2.carbon.identity.api.server.idp.v1/src/main/java/org/wso2/carbon/identity/api/server/idp/v1/impl/FederatedAuthenticatorConfigBuilderFactory.java b/components/org.wso2.carbon.identity.api.server.idp/org.wso2.carbon.identity.api.server.idp.v1/src/main/java/org/wso2/carbon/identity/api/server/idp/v1/impl/FederatedAuthenticatorConfigBuilderFactory.java new file mode 100644 index 0000000000..f769c1e31b --- /dev/null +++ b/components/org.wso2.carbon.identity.api.server.idp/org.wso2.carbon.identity.api.server.idp.v1/src/main/java/org/wso2/carbon/identity/api/server/idp/v1/impl/FederatedAuthenticatorConfigBuilderFactory.java @@ -0,0 +1,175 @@ +/* + * Copyright (c) 2024, WSO2 LLC. (http://www.wso2.com). + * + * WSO2 LLC. 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.wso2.carbon.identity.api.server.idp.v1.impl; + +import org.wso2.carbon.identity.api.server.idp.common.Constants; +import org.wso2.carbon.identity.api.server.idp.v1.model.Endpoint; +import org.wso2.carbon.identity.application.common.ApplicationAuthenticatorService; +import org.wso2.carbon.identity.application.common.model.FederatedAuthenticatorConfig; +import org.wso2.carbon.identity.application.common.model.Property; +import org.wso2.carbon.identity.application.common.model.UserDefinedAuthenticatorEndpointConfig; +import org.wso2.carbon.identity.application.common.model.UserDefinedFederatedAuthenticatorConfig; +import org.wso2.carbon.identity.base.AuthenticatorPropertyConstants.DefinedByType; +import org.wso2.carbon.idp.mgt.IdentityProviderManagementClientException; + +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * The factory class for creating instances of FederatedAuthenticatorConfig depending on the definedBy type. + * Returns FederatedAuthenticatorConfig for SYSTEM types and UserDefinedFederatedAuthenticatorConfig for USER types. + */ +public class FederatedAuthenticatorConfigBuilderFactory { + + private static FederatedAuthenticatorConfig createFederatedAuthenticatorConfig(Builder builder) + throws IdentityProviderManagementClientException { + + FederatedAuthenticatorConfig config; + if (DefinedByType.SYSTEM.toString().equals(builder.definedByType)) { + config = createSystemDefinedFederatedAuthenticator(builder); + } else { + config = createUserDefinedFederatedAuthenticator(builder); + } + + config.setName(builder.authenticatorName); + config.setDisplayName(builder.displayName); + config.setEnabled(builder.isEnabled); + + return config; + } + + private static FederatedAuthenticatorConfig createSystemDefinedFederatedAuthenticator( + Builder builder) throws IdentityProviderManagementClientException { + + validateSystemDefinedFederatedAuthenticatorModel(builder); + FederatedAuthenticatorConfig authConfig = new FederatedAuthenticatorConfig(); + authConfig.setDefinedByType(DefinedByType.SYSTEM); + authConfig.setProperties(builder.properties.toArray(new Property[0])); + return authConfig; + } + + private static void validateSystemDefinedFederatedAuthenticatorModel(Builder builder) + throws IdentityProviderManagementClientException { + + // The System-defined authenticator configs must not have endpoint configurations; throw an error if they do. + if (builder.endpoint != null) { + Constants.ErrorMessage error = Constants.ErrorMessage.ERROR_CODE_ENDPOINT_PROVIDED_FOR_SYSTEM_AUTH; + throw new IdentityProviderManagementClientException(error.getCode(), String.format(error.getDescription(), + builder.authenticatorName)); + } + + // Check if there is an authenticator registered in the system for the given authenticator ID. + if (ApplicationAuthenticatorService.getInstance() + .getFederatedAuthenticatorByName(builder.authenticatorName) == null) { + Constants.ErrorMessage error = Constants.ErrorMessage.ERROR_CODE_NO_SYSTEM_AUTHENTICATOR_FOUND; + throw new IdentityProviderManagementClientException(error.getCode(), + String.format(error.getDescription(), builder.authenticatorName)); + } + } + + private static UserDefinedFederatedAuthenticatorConfig createUserDefinedFederatedAuthenticator(Builder builder) + throws IdentityProviderManagementClientException { + + validateUserDefinedFederatedAuthenticatorModel(builder); + + UserDefinedFederatedAuthenticatorConfig authConfig = new UserDefinedFederatedAuthenticatorConfig(); + UserDefinedAuthenticatorEndpointConfig.UserDefinedAuthenticatorEndpointConfigBuilder endpointConfigBuilder = + new UserDefinedAuthenticatorEndpointConfig.UserDefinedAuthenticatorEndpointConfigBuilder(); + endpointConfigBuilder.uri(builder.endpoint.getUri()); + endpointConfigBuilder.authenticationType(builder.endpoint.getAuthentication().getType().toString()); + endpointConfigBuilder.authenticationProperties(builder.endpoint.getAuthentication().getProperties() + .entrySet().stream().collect(Collectors.toMap( + Map.Entry::getKey, entry -> entry.getValue().toString()))); + authConfig.setEndpointConfig(endpointConfigBuilder.build()); + + return authConfig; + } + + private static void validateUserDefinedFederatedAuthenticatorModel(Builder builder) + throws IdentityProviderManagementClientException { + + // The User-defined authenticator configs must not have properties configurations; throw an error if they do. + if (builder.properties == null || !builder.properties.isEmpty()) { + Constants.ErrorMessage error = Constants.ErrorMessage.ERROR_CODE_PROPERTIES_PROVIDED_FOR_USER_AUTH; + throw new IdentityProviderManagementClientException(error.getCode(), + String.format(error.getDescription(), builder.authenticatorName)); + } + + // The User-defined authenticator configs must have endpoint configurations; throw an error if they don't. + if (builder.endpoint == null) { + Constants.ErrorMessage error = Constants.ErrorMessage.ERROR_CODE_NO_ENDPOINT_PROVIDED; + throw new IdentityProviderManagementClientException(error.getCode(), + String.format(error.getDescription(), builder.authenticatorName)); + } + } + + /** + * Builder class to build FederatedAuthenticatorConfig. + */ + public static class Builder { + private String definedByType; + private String authenticatorName; + private String displayName; + private Endpoint endpoint; + private List properties; + private Boolean isEnabled; + + public Builder definedByType(String definedByType) { + + this.definedByType = definedByType; + return this; + } + + public Builder authenticatorName(String authenticatorName) { + + this.authenticatorName = authenticatorName; + return this; + } + + public Builder displayName(String displayName) { + + this.displayName = displayName; + return this; + } + + public Builder endpoint(Endpoint endpoint) { + + this.endpoint = endpoint; + return this; + } + + public Builder properties(List properties) { + + this.properties = properties; + return this; + } + + public Builder enabled(Boolean enabled) { + + isEnabled = enabled; + return this; + } + + public FederatedAuthenticatorConfig build() throws IdentityProviderManagementClientException { + + return FederatedAuthenticatorConfigBuilderFactory.createFederatedAuthenticatorConfig(this); + } + } +} From b4df83fcc12fdd870b624d9961861688c32269df Mon Sep 17 00:00:00 2001 From: Thisara-Welmilla Date: Wed, 13 Nov 2024 08:03:54 +0530 Subject: [PATCH 05/10] Update APIs to support custom authentication management. --- .../api/server/idp/common/Constants.java | 10 ++--- .../v1/core/ServerIdpManagementService.java | 42 ++++++++++++------- ...atedAuthenticatorConfigBuilderFactory.java | 17 ++------ 3 files changed, 37 insertions(+), 32 deletions(-) diff --git a/components/org.wso2.carbon.identity.api.server.idp/org.wso2.carbon.identity.api.server.idp.common/src/main/java/org/wso2/carbon/identity/api/server/idp/common/Constants.java b/components/org.wso2.carbon.identity.api.server.idp/org.wso2.carbon.identity.api.server.idp.common/src/main/java/org/wso2/carbon/identity/api/server/idp/common/Constants.java index 7b96242696..858226befd 100644 --- a/components/org.wso2.carbon.identity.api.server.idp/org.wso2.carbon.identity.api.server.idp.common/src/main/java/org/wso2/carbon/identity/api/server/idp/common/Constants.java +++ b/components/org.wso2.carbon.identity.api.server.idp/org.wso2.carbon.identity.api.server.idp.common/src/main/java/org/wso2/carbon/identity/api/server/idp/common/Constants.java @@ -146,13 +146,13 @@ public enum ErrorMessage { ERROR_CODE_ERROR_LISTING_TRUSTED_TOKEN_ISSUERS("60021", "Unable to list existing trusted token issuers.", "Server encountered an error while listing the trusted token issuers."), - ERROR_CODE_ENDPOINT_PROVIDED_FOR_SYSTEM_AUTH("60039", "No endpoint configuration is allowed " + - "for system defined authenticators.", "No endpoint configuration must be " + + ERROR_CODE_ENDPOINT_PROVIDED_FOR_SYSTEM_AUTH("60039", "Invalid Request.", + "No endpoint configuration must be " + "provided for the system defined federated authenticators %s."), - ERROR_CODE_PROPERTIES_PROVIDED_FOR_USER_AUTH("60040", "No properties are allowed for " + - "user defined authenticators.", "No properties must be provided for the user defined " + + ERROR_CODE_PROPERTIES_PROVIDED_FOR_USER_AUTH("60040", "Invalid Request.", + "No properties must be provided for the user defined " + "federated authenticators %s."), - ERROR_CODE_NO_ENDPOINT_PROVIDED("60041", "No endpoint provided.", "Endpoint " + + ERROR_CODE_NO_ENDPOINT_PROVIDED("60041", "Invalid Request.", "Endpoint " + "configuration must be provided for the user defined federated authenticators %s."), ERROR_CODE_NON_DECODABLE_AUTH_ID("60042", "Non-decodable authenticator ID.", "Unable to decode the provided authenticator ID %s."), diff --git a/components/org.wso2.carbon.identity.api.server.idp/org.wso2.carbon.identity.api.server.idp.v1/src/main/java/org/wso2/carbon/identity/api/server/idp/v1/core/ServerIdpManagementService.java b/components/org.wso2.carbon.identity.api.server.idp/org.wso2.carbon.identity.api.server.idp.v1/src/main/java/org/wso2/carbon/identity/api/server/idp/v1/core/ServerIdpManagementService.java index 34602068d7..516de84c9a 100644 --- a/components/org.wso2.carbon.identity.api.server.idp/org.wso2.carbon.identity.api.server.idp.v1/src/main/java/org/wso2/carbon/identity/api/server/idp/v1/core/ServerIdpManagementService.java +++ b/components/org.wso2.carbon.identity.api.server.idp/org.wso2.carbon.identity.api.server.idp.v1/src/main/java/org/wso2/carbon/identity/api/server/idp/v1/core/ServerIdpManagementService.java @@ -146,6 +146,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Optional; import java.util.Set; import java.util.function.Function; import java.util.stream.Collectors; @@ -1775,15 +1776,15 @@ private void updateFederatedAuthenticatorConfig(IdentityProvider idp, FederatedA List fedAuthConfigs = new ArrayList<>(); for (FederatedAuthenticator authenticator : federatedAuthenticators) { String authenticatorName = getDecodedAuthenticatorName(authenticator.getAuthenticatorId()); - String definedByType; + DefinedByType definedByType; if (isNewFederatedAuthenticator) { - definedByType = resolveDefinedByTypeForCreateFederatedAuthenticator( - authenticator.getDefinedBy().toString()).toString(); + definedByType = resolveDefinedByTypeToCreateFederatedAuthenticator( + authenticator.getDefinedBy()); } else { - definedByType = resolveDefinedByTypeForUpdateFederatedAuthenticator(authenticatorName).toString(); + definedByType = resolveDefinedByTypeToUpdateFederatedAuthenticator(authenticatorName); } - if (DefinedByType.SYSTEM.toString().equals(definedByType)) { + if (DefinedByType.SYSTEM == definedByType) { validateAuthenticatorProperties(authenticatorName, authenticator.getProperties()); } @@ -1794,8 +1795,9 @@ private void updateFederatedAuthenticatorConfig(IdentityProvider idp, FederatedA builder.enabled(authenticator.getIsEnabled()); builder.displayName(getDisplayNameOfAuthenticator(authenticatorName)); builder.endpoint(authenticator.getEndpoint()); - List properties = authenticator.getProperties().stream().map(propertyToInternal) - .collect(Collectors.toList()); + List properties = Optional.ofNullable(authenticator.getProperties()) + .map(props -> props.stream().map(propertyToInternal).collect(Collectors.toList())) + .orElse(null); builder.properties(properties); FederatedAuthenticatorConfig authConfig = builder.build(); @@ -2701,6 +2703,12 @@ private IdentityProvider createIdPClone(IdentityProvider idP) { Gson gson = new Gson(); IdentityProvider clonedIdentityProvider = gson.fromJson(gson.toJson(idP), IdentityProvider.class); + if (idP.getFederatedAuthenticatorConfigs().length == 1 && + idP.getFederatedAuthenticatorConfigs()[0].getDefinedByType() == DefinedByType.USER) { + UserDefinedFederatedAuthenticatorConfig clonedFedAuth = gson.fromJson(gson.toJson( + idP.getFederatedAuthenticatorConfigs()[0]), UserDefinedFederatedAuthenticatorConfig.class); + clonedIdentityProvider.setFederatedAuthenticatorConfigs(new FederatedAuthenticatorConfig[]{clonedFedAuth}); + } return clonedIdentityProvider; } @@ -2848,8 +2856,8 @@ private FederatedAuthenticatorConfig updateFederatedAuthenticatorConfig(String f FederatedAuthenticatorPUTRequest authenticator) throws IdentityProviderManagementClientException { String authenticatorName = getDecodedAuthenticatorName(federatedAuthenticatorId); - String definedByType = resolveDefinedByTypeForUpdateFederatedAuthenticator(authenticatorName).toString(); - if (DefinedByType.SYSTEM.toString().equals(definedByType)) { + DefinedByType definedByType = resolveDefinedByTypeToUpdateFederatedAuthenticator(authenticatorName); + if (DefinedByType.SYSTEM == definedByType) { validateAuthenticatorProperties(authenticatorName, authenticator.getProperties()); } @@ -2860,24 +2868,26 @@ private FederatedAuthenticatorConfig updateFederatedAuthenticatorConfig(String f builder.enabled(authenticator.getIsEnabled()); builder.displayName(getDisplayNameOfAuthenticator(authenticatorName)); builder.endpoint(authenticator.getEndpoint()); - List properties = authenticator.getProperties().stream().map(propertyToInternal) - .collect(Collectors.toList()); + List properties = Optional.ofNullable(authenticator.getProperties()) + .map(props -> props.stream().map(propertyToInternal).collect(Collectors.toList())) + .orElse(null); builder.properties(properties); return builder.build(); } - private DefinedByType resolveDefinedByTypeForCreateFederatedAuthenticator(String definedByType) { + private DefinedByType resolveDefinedByTypeToCreateFederatedAuthenticator( + FederatedAuthenticator.DefinedByEnum definedByType) { /* For new federated authenticators: If 'definedByType' is not null, use the value provided in the request payload. If not, default to SYSTEM. */ if (definedByType != null) { - return DefinedByType.valueOf(definedByType); + return DefinedByType.valueOf(definedByType.toString()); } return DefinedByType.SYSTEM; } - private DefinedByType resolveDefinedByTypeForUpdateFederatedAuthenticator(String authenticatorName) { + private DefinedByType resolveDefinedByTypeToUpdateFederatedAuthenticator(String authenticatorName) { /* For existing federated authenticators, disregard any value provided in the request payload. Instead, resolve and retrieve the 'definedBy' type of the corresponding existing authenticator. @@ -3898,6 +3908,10 @@ private void validateAuthenticatorProperties(String authenticatorName, List properties) throws IdentityProviderManagementClientException { + if (properties == null) { + return; + } + if (IdentityApplicationConstants.Authenticator.SAML2SSO.FED_AUTH_NAME.equals(authenticatorName)) { validateSamlMetadata(properties); } diff --git a/components/org.wso2.carbon.identity.api.server.idp/org.wso2.carbon.identity.api.server.idp.v1/src/main/java/org/wso2/carbon/identity/api/server/idp/v1/impl/FederatedAuthenticatorConfigBuilderFactory.java b/components/org.wso2.carbon.identity.api.server.idp/org.wso2.carbon.identity.api.server.idp.v1/src/main/java/org/wso2/carbon/identity/api/server/idp/v1/impl/FederatedAuthenticatorConfigBuilderFactory.java index f769c1e31b..4250a67985 100644 --- a/components/org.wso2.carbon.identity.api.server.idp/org.wso2.carbon.identity.api.server.idp.v1/src/main/java/org/wso2/carbon/identity/api/server/idp/v1/impl/FederatedAuthenticatorConfigBuilderFactory.java +++ b/components/org.wso2.carbon.identity.api.server.idp/org.wso2.carbon.identity.api.server.idp.v1/src/main/java/org/wso2/carbon/identity/api/server/idp/v1/impl/FederatedAuthenticatorConfigBuilderFactory.java @@ -20,7 +20,6 @@ import org.wso2.carbon.identity.api.server.idp.common.Constants; import org.wso2.carbon.identity.api.server.idp.v1.model.Endpoint; -import org.wso2.carbon.identity.application.common.ApplicationAuthenticatorService; import org.wso2.carbon.identity.application.common.model.FederatedAuthenticatorConfig; import org.wso2.carbon.identity.application.common.model.Property; import org.wso2.carbon.identity.application.common.model.UserDefinedAuthenticatorEndpointConfig; @@ -42,7 +41,7 @@ private static FederatedAuthenticatorConfig createFederatedAuthenticatorConfig(B throws IdentityProviderManagementClientException { FederatedAuthenticatorConfig config; - if (DefinedByType.SYSTEM.toString().equals(builder.definedByType)) { + if (DefinedByType.SYSTEM == builder.definedByType) { config = createSystemDefinedFederatedAuthenticator(builder); } else { config = createUserDefinedFederatedAuthenticator(builder); @@ -74,14 +73,6 @@ private static void validateSystemDefinedFederatedAuthenticatorModel(Builder bui throw new IdentityProviderManagementClientException(error.getCode(), String.format(error.getDescription(), builder.authenticatorName)); } - - // Check if there is an authenticator registered in the system for the given authenticator ID. - if (ApplicationAuthenticatorService.getInstance() - .getFederatedAuthenticatorByName(builder.authenticatorName) == null) { - Constants.ErrorMessage error = Constants.ErrorMessage.ERROR_CODE_NO_SYSTEM_AUTHENTICATOR_FOUND; - throw new IdentityProviderManagementClientException(error.getCode(), - String.format(error.getDescription(), builder.authenticatorName)); - } } private static UserDefinedFederatedAuthenticatorConfig createUserDefinedFederatedAuthenticator(Builder builder) @@ -106,7 +97,7 @@ private static void validateUserDefinedFederatedAuthenticatorModel(Builder build throws IdentityProviderManagementClientException { // The User-defined authenticator configs must not have properties configurations; throw an error if they do. - if (builder.properties == null || !builder.properties.isEmpty()) { + if (builder.properties != null) { Constants.ErrorMessage error = Constants.ErrorMessage.ERROR_CODE_PROPERTIES_PROVIDED_FOR_USER_AUTH; throw new IdentityProviderManagementClientException(error.getCode(), String.format(error.getDescription(), builder.authenticatorName)); @@ -124,14 +115,14 @@ private static void validateUserDefinedFederatedAuthenticatorModel(Builder build * Builder class to build FederatedAuthenticatorConfig. */ public static class Builder { - private String definedByType; + private DefinedByType definedByType; private String authenticatorName; private String displayName; private Endpoint endpoint; private List properties; private Boolean isEnabled; - public Builder definedByType(String definedByType) { + public Builder definedByType(DefinedByType definedByType) { this.definedByType = definedByType; return this; From 3da9303531282656e3cdee2a722cf97d38b90598 Mon Sep 17 00:00:00 2001 From: Thisara-Welmilla Date: Thu, 14 Nov 2024 14:26:10 +0530 Subject: [PATCH 06/10] Update APIs to support custom authentication management. --- .../api/server/idp/common/Constants.java | 6 +- .../v1/core/ServerIdpManagementService.java | 229 +---------- ...atedAuthenticatorConfigBuilderFactory.java | 380 +++++++++++++++--- pom.xml | 2 +- 4 files changed, 332 insertions(+), 285 deletions(-) diff --git a/components/org.wso2.carbon.identity.api.server.idp/org.wso2.carbon.identity.api.server.idp.common/src/main/java/org/wso2/carbon/identity/api/server/idp/common/Constants.java b/components/org.wso2.carbon.identity.api.server.idp/org.wso2.carbon.identity.api.server.idp.common/src/main/java/org/wso2/carbon/identity/api/server/idp/common/Constants.java index 858226befd..d578b8f918 100644 --- a/components/org.wso2.carbon.identity.api.server.idp/org.wso2.carbon.identity.api.server.idp.common/src/main/java/org/wso2/carbon/identity/api/server/idp/common/Constants.java +++ b/components/org.wso2.carbon.identity.api.server.idp/org.wso2.carbon.identity.api.server.idp.common/src/main/java/org/wso2/carbon/identity/api/server/idp/common/Constants.java @@ -146,13 +146,13 @@ public enum ErrorMessage { ERROR_CODE_ERROR_LISTING_TRUSTED_TOKEN_ISSUERS("60021", "Unable to list existing trusted token issuers.", "Server encountered an error while listing the trusted token issuers."), - ERROR_CODE_ENDPOINT_PROVIDED_FOR_SYSTEM_AUTH("60039", "Invalid Request.", + ERROR_CODE_ENDPOINT_PROVIDED_FOR_SYSTEM_AUTH("60039", "No endpoint configuration is allowed.", "No endpoint configuration must be " + "provided for the system defined federated authenticators %s."), - ERROR_CODE_PROPERTIES_PROVIDED_FOR_USER_AUTH("60040", "Invalid Request.", + ERROR_CODE_PROPERTIES_PROVIDED_FOR_USER_AUTH("60040", "No properties are allowed.", "No properties must be provided for the user defined " + "federated authenticators %s."), - ERROR_CODE_NO_ENDPOINT_PROVIDED("60041", "Invalid Request.", "Endpoint " + + ERROR_CODE_NO_ENDPOINT_PROVIDED("60041", "No endpoint provided.", "Endpoint " + "configuration must be provided for the user defined federated authenticators %s."), ERROR_CODE_NON_DECODABLE_AUTH_ID("60042", "Non-decodable authenticator ID.", "Unable to decode the provided authenticator ID %s."), diff --git a/components/org.wso2.carbon.identity.api.server.idp/org.wso2.carbon.identity.api.server.idp.v1/src/main/java/org/wso2/carbon/identity/api/server/idp/v1/core/ServerIdpManagementService.java b/components/org.wso2.carbon.identity.api.server.idp/org.wso2.carbon.identity.api.server.idp.v1/src/main/java/org/wso2/carbon/identity/api/server/idp/v1/core/ServerIdpManagementService.java index 516de84c9a..425f298f00 100644 --- a/components/org.wso2.carbon.identity.api.server.idp/org.wso2.carbon.identity.api.server.idp.v1/src/main/java/org/wso2/carbon/identity/api/server/idp/v1/core/ServerIdpManagementService.java +++ b/components/org.wso2.carbon.identity.api.server.idp/org.wso2.carbon.identity.api.server.idp.v1/src/main/java/org/wso2/carbon/identity/api/server/idp/v1/core/ServerIdpManagementService.java @@ -44,13 +44,11 @@ import org.wso2.carbon.identity.api.server.idp.v1.impl.FederatedAuthenticatorConfigBuilderFactory; import org.wso2.carbon.identity.api.server.idp.v1.model.AssociationRequest; import org.wso2.carbon.identity.api.server.idp.v1.model.AssociationResponse; -import org.wso2.carbon.identity.api.server.idp.v1.model.AuthenticationType; import org.wso2.carbon.identity.api.server.idp.v1.model.Certificate; import org.wso2.carbon.identity.api.server.idp.v1.model.Claim; import org.wso2.carbon.identity.api.server.idp.v1.model.Claims; import org.wso2.carbon.identity.api.server.idp.v1.model.ConnectedApp; import org.wso2.carbon.identity.api.server.idp.v1.model.ConnectedApps; -import org.wso2.carbon.identity.api.server.idp.v1.model.Endpoint; import org.wso2.carbon.identity.api.server.idp.v1.model.FederatedAuthenticator; import org.wso2.carbon.identity.api.server.idp.v1.model.FederatedAuthenticatorListItem; import org.wso2.carbon.identity.api.server.idp.v1.model.FederatedAuthenticatorListResponse; @@ -96,7 +94,6 @@ import org.wso2.carbon.identity.application.common.model.ProvisioningConnectorConfig; import org.wso2.carbon.identity.application.common.model.RoleMapping; import org.wso2.carbon.identity.application.common.model.SubProperty; -import org.wso2.carbon.identity.application.common.model.UserDefinedAuthenticatorEndpointConfig; import org.wso2.carbon.identity.application.common.model.UserDefinedFederatedAuthenticatorConfig; import org.wso2.carbon.identity.application.common.util.IdentityApplicationConstants; import org.wso2.carbon.identity.base.AuthenticatorPropertyConstants.DefinedByType; @@ -146,7 +143,6 @@ import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.Optional; import java.util.Set; import java.util.function.Function; import java.util.stream.Collectors; @@ -1783,23 +1779,8 @@ private void updateFederatedAuthenticatorConfig(IdentityProvider idp, FederatedA } else { definedByType = resolveDefinedByTypeToUpdateFederatedAuthenticator(authenticatorName); } - - if (DefinedByType.SYSTEM == definedByType) { - validateAuthenticatorProperties(authenticatorName, authenticator.getProperties()); - } - - FederatedAuthenticatorConfigBuilderFactory.Builder builder = - new FederatedAuthenticatorConfigBuilderFactory.Builder(); - builder.authenticatorName(authenticatorName); - builder.definedByType(definedByType); - builder.enabled(authenticator.getIsEnabled()); - builder.displayName(getDisplayNameOfAuthenticator(authenticatorName)); - builder.endpoint(authenticator.getEndpoint()); - List properties = Optional.ofNullable(authenticator.getProperties()) - .map(props -> props.stream().map(propertyToInternal).collect(Collectors.toList())) - .orElse(null); - builder.properties(properties); - FederatedAuthenticatorConfig authConfig = builder.build(); + FederatedAuthenticatorConfig authConfig = FederatedAuthenticatorConfigBuilderFactory.build( + authenticator, authenticatorName, definedByType); fedAuthConfigs.add(authConfig); @@ -1817,30 +1798,6 @@ private void updateFederatedAuthenticatorConfig(IdentityProvider idp, FederatedA } } - /** - * Returns the 'DisplayName' property of the federated authenticator identified by authenticator name. - * - * @param authenticatorName Federated authenticator name. - * @return Display name of authenticator. - */ - private String getDisplayNameOfAuthenticator(String authenticatorName) { - - try { - FederatedAuthenticatorConfig[] authenticatorConfigs = - IdentityProviderServiceHolder.getIdentityProviderManager() - .getAllFederatedAuthenticators(); - for (FederatedAuthenticatorConfig config : authenticatorConfigs) { - - if (StringUtils.equals(config.getName(), authenticatorName)) { - return config.getDisplayName(); - } - } - } catch (IdentityProviderManagementException e) { - throw handleIdPException(e, Constants.ErrorMessage.ERROR_CODE_ERROR_ADDING_IDP, null); - } - return null; - } - private void updateOutboundConnectorConfig(IdentityProvider idp, OutboundProvisioningRequest outboundProvisioningRequest) { @@ -2857,23 +2814,8 @@ private FederatedAuthenticatorConfig updateFederatedAuthenticatorConfig(String f String authenticatorName = getDecodedAuthenticatorName(federatedAuthenticatorId); DefinedByType definedByType = resolveDefinedByTypeToUpdateFederatedAuthenticator(authenticatorName); - if (DefinedByType.SYSTEM == definedByType) { - validateAuthenticatorProperties(authenticatorName, authenticator.getProperties()); - } - FederatedAuthenticatorConfigBuilderFactory.Builder builder = new FederatedAuthenticatorConfigBuilderFactory - .Builder(); - builder.authenticatorName(authenticatorName); - builder.definedByType(definedByType); - builder.enabled(authenticator.getIsEnabled()); - builder.displayName(getDisplayNameOfAuthenticator(authenticatorName)); - builder.endpoint(authenticator.getEndpoint()); - List properties = Optional.ofNullable(authenticator.getProperties()) - .map(props -> props.stream().map(propertyToInternal).collect(Collectors.toList())) - .orElse(null); - builder.properties(properties); - - return builder.build(); + return FederatedAuthenticatorConfigBuilderFactory.build(authenticator, authenticatorName, definedByType); } private DefinedByType resolveDefinedByTypeToCreateFederatedAuthenticator( @@ -2901,105 +2843,6 @@ private DefinedByType resolveDefinedByTypeToUpdateFederatedAuthenticator(String return DefinedByType.USER; } - /** - * Verify if scopes have not been set in both Scopes field and Additional Query Parameters field - * - * @param oidcAuthenticatorProperties Authenticator properties of OIDC authenticator. - */ - private void validateDuplicateOpenIDConnectScopes(List - oidcAuthenticatorProperties) { - - if (oidcAuthenticatorProperties != null) { - boolean scopesFieldFilled = false; - boolean queryParamsScopesFilled = false; - for (org.wso2.carbon.identity.api.server.idp.v1 - .model.Property oidcAuthenticatorProperty : oidcAuthenticatorProperties) { - if (IdentityApplicationConstants.Authenticator.OIDC.SCOPES.equals(oidcAuthenticatorProperty.getKey()) && - StringUtils.isNotBlank(oidcAuthenticatorProperty.getValue())) { - scopesFieldFilled = true; - } - if (IdentityApplicationConstants.Authenticator.OIDC.QUERY_PARAMS.equals - (oidcAuthenticatorProperty.getKey()) - && oidcAuthenticatorProperty.getValue().contains("scope=")) { - queryParamsScopesFilled = true; - } - } - if (scopesFieldFilled && queryParamsScopesFilled) { - throw handleException(Response.Status.BAD_REQUEST, Constants.ErrorMessage - .ERROR_CODE_DUPLICATE_OIDC_SCOPES, null); - } - } - } - - /** - * Verify if scopes contain `openid`. - * - * @param oidcAuthenticatorProperties Authenticator properties of OIDC authenticator. - */ - private void validateDefaultOpenIDConnectScopes(List - oidcAuthenticatorProperties) { - - if (oidcAuthenticatorProperties != null) { - for (org.wso2.carbon.identity.api.server.idp.v1 - .model.Property oidcAuthenticatorProperty : oidcAuthenticatorProperties) { - if (IdentityApplicationConstants.Authenticator.OIDC.SCOPES.equals(oidcAuthenticatorProperty.getKey())) { - String scopes = oidcAuthenticatorProperty.getValue(); - if (StringUtils.isNotBlank(scopes) && !scopes.contains("openid")) { - throw handleException(Response.Status.BAD_REQUEST, Constants.ErrorMessage - .ERROR_CODE_INVALID_OIDC_SCOPES, null); - } - } - } - } - } - - /** - * If selectMode property is set as saml metadata file configuration mode, this function validates whether a - * valid base-64 encoded SAML metadata file content is provided with the property key 'meta_data_saml'. If found, - * it will decode the file content and update the value of 'meta_data_saml' property with decoded content. - * - * @param samlAuthenticatorProperties Authenticator properties of SAML authenticator. - */ - private void validateSamlMetadata(List - samlAuthenticatorProperties) { - - if (samlAuthenticatorProperties != null) { - for (org.wso2.carbon.identity.api.server.idp.v1.model.Property property : samlAuthenticatorProperties) { - - if (Constants.SELECT_MODE.equals(property.getKey()) && - Constants.SELECT_MODE_METADATA.equals(property.getValue())) { - // SAML metadata file configuration has been selected. Hence we need to validate whether valid SAML - // metadata (property with key = 'meta_data_saml') is sent. - - boolean validMetadataFound = false; - String encodedData = null; - int positionOfMetadataKey = -1; - - for (int i = 0; i < samlAuthenticatorProperties.size(); i++) { - if (Constants.META_DATA_SAML.equals(samlAuthenticatorProperties.get(i).getKey()) && - StringUtils.isNotBlank - (samlAuthenticatorProperties.get(i).getValue())) { - validMetadataFound = true; - encodedData = samlAuthenticatorProperties.get(i).getValue(); - positionOfMetadataKey = i; - } - } - if (validMetadataFound) { - String metadata = base64Decode(encodedData); - // Add decoded data to property list. - org.wso2.carbon.identity.api.server.idp.v1.model.Property metadataProperty = - samlAuthenticatorProperties.get(positionOfMetadataKey); - metadataProperty.setValue(metadata); - samlAuthenticatorProperties.set(positionOfMetadataKey, metadataProperty); - } else { - throw handleException(Response.Status.BAD_REQUEST, Constants.ErrorMessage - .ERROR_CODE_INVALID_SAML_METADATA, null); - } - } - } - } - } - /** * Verify whether the sent authenticatorId is a supported authenticator type by the server. * @@ -3076,55 +2919,13 @@ private FederatedAuthenticator createFederatedAuthenticator(String authenticator } FederatedAuthenticator federatedAuthenticator = new FederatedAuthenticator(); if (config != null) { + federatedAuthenticator = FederatedAuthenticatorConfigBuilderFactory.build(config); federatedAuthenticator.setAuthenticatorId(authenticatorId); - federatedAuthenticator.setName(config.getName()); - federatedAuthenticator.setIsEnabled(config.isEnabled()); federatedAuthenticator.setIsDefault(isDefaultAuthenticator); - FederatedAuthenticatorConfig federatedAuthenticatorConfig = - ApplicationAuthenticatorService.getInstance().getFederatedAuthenticatorByName( - config.getName()); - if (federatedAuthenticatorConfig != null) { - String[] tags = federatedAuthenticatorConfig.getTags(); - if (ArrayUtils.isNotEmpty(tags)) { - federatedAuthenticator.setTags(Arrays.asList(tags)); - } - } - - if (DefinedByType.SYSTEM == config.getDefinedByType()) { - federatedAuthenticator.setDefinedBy(FederatedAuthenticator.DefinedByEnum.SYSTEM); - List properties = - Arrays.stream(config.getProperties()).map(propertyToExternal).collect(Collectors.toList()); - federatedAuthenticator.setProperties(properties); - } else { - federatedAuthenticator.setDefinedBy(FederatedAuthenticator.DefinedByEnum.USER); - resolveEndpointConfiguration(federatedAuthenticator, config); - } - } return federatedAuthenticator; } - private void resolveEndpointConfiguration(FederatedAuthenticator authenticator, - FederatedAuthenticatorConfig config) throws IdentityProviderManagementServerException { - - try { - UserDefinedFederatedAuthenticatorConfig userDefinedConfig = - (UserDefinedFederatedAuthenticatorConfig) config; - UserDefinedAuthenticatorEndpointConfig endpointConfig = userDefinedConfig.getEndpointConfig(); - - AuthenticationType authenticationType = new AuthenticationType(); - authenticationType.setType(AuthenticationType.TypeEnum.fromValue(endpointConfig.getEndpointConfig() - .getAuthentication().getType().toString())); - - Endpoint endpoint = new Endpoint(); - endpoint.setUri(endpointConfig.getEndpointConfig().getUri()); - authenticator.setEndpoint(endpoint); - } catch (ClassCastException e) { - throw new IdentityProviderManagementServerException(String.format("Error occurred while resolving" + - " endpoint configuration of the authenticator %s.", authenticator.getName()), e); - } - } - /** * Create external OutboundConnector from Provisioning Config. * @@ -3903,26 +3704,4 @@ private String getDecodedAuthenticatorName(String authId) throws IdentityProvide String.format(error.getDescription(), authId)); } } - - private void validateAuthenticatorProperties(String authenticatorName, - List properties) - throws IdentityProviderManagementClientException { - - if (properties == null) { - return; - } - - if (IdentityApplicationConstants.Authenticator.SAML2SSO.FED_AUTH_NAME.equals(authenticatorName)) { - validateSamlMetadata(properties); - } - if (IdentityApplicationConstants.Authenticator.OIDC.FED_AUTH_NAME.equals(authenticatorName)) { - validateDuplicateOpenIDConnectScopes(properties); - validateDefaultOpenIDConnectScopes(properties); - } - - if (!areAllDistinct(properties)) { - Constants.ErrorMessage error = Constants.ErrorMessage.ERROR_CODE_INVALID_INPUT; - throw new IdentityProviderManagementClientException(error.getCode(), error.getDescription()); - } - } } diff --git a/components/org.wso2.carbon.identity.api.server.idp/org.wso2.carbon.identity.api.server.idp.v1/src/main/java/org/wso2/carbon/identity/api/server/idp/v1/impl/FederatedAuthenticatorConfigBuilderFactory.java b/components/org.wso2.carbon.identity.api.server.idp/org.wso2.carbon.identity.api.server.idp.v1/src/main/java/org/wso2/carbon/identity/api/server/idp/v1/impl/FederatedAuthenticatorConfigBuilderFactory.java index 4250a67985..7f2d7800a6 100644 --- a/components/org.wso2.carbon.identity.api.server.idp/org.wso2.carbon.identity.api.server.idp.v1/src/main/java/org/wso2/carbon/identity/api/server/idp/v1/impl/FederatedAuthenticatorConfigBuilderFactory.java +++ b/components/org.wso2.carbon.identity.api.server.idp/org.wso2.carbon.identity.api.server.idp.v1/src/main/java/org/wso2/carbon/identity/api/server/idp/v1/impl/FederatedAuthenticatorConfigBuilderFactory.java @@ -18,74 +18,178 @@ package org.wso2.carbon.identity.api.server.idp.v1.impl; +import org.apache.commons.lang.ArrayUtils; +import org.apache.commons.lang.StringUtils; import org.wso2.carbon.identity.api.server.idp.common.Constants; +import org.wso2.carbon.identity.api.server.idp.common.IdentityProviderServiceHolder; +import org.wso2.carbon.identity.api.server.idp.v1.model.AuthenticationType; import org.wso2.carbon.identity.api.server.idp.v1.model.Endpoint; +import org.wso2.carbon.identity.api.server.idp.v1.model.FederatedAuthenticator; +import org.wso2.carbon.identity.api.server.idp.v1.model.FederatedAuthenticatorPUTRequest; +import org.wso2.carbon.identity.application.common.ApplicationAuthenticatorService; import org.wso2.carbon.identity.application.common.model.FederatedAuthenticatorConfig; import org.wso2.carbon.identity.application.common.model.Property; import org.wso2.carbon.identity.application.common.model.UserDefinedAuthenticatorEndpointConfig; import org.wso2.carbon.identity.application.common.model.UserDefinedFederatedAuthenticatorConfig; +import org.wso2.carbon.identity.application.common.util.IdentityApplicationConstants; import org.wso2.carbon.identity.base.AuthenticatorPropertyConstants.DefinedByType; import org.wso2.carbon.idp.mgt.IdentityProviderManagementClientException; +import org.wso2.carbon.idp.mgt.IdentityProviderManagementException; +import org.wso2.carbon.idp.mgt.IdentityProviderManagementServerException; +import java.nio.charset.StandardCharsets; +import java.util.Arrays; +import java.util.Base64; import java.util.List; import java.util.Map; +import java.util.Optional; +import java.util.function.Function; import java.util.stream.Collectors; +import static org.wso2.carbon.identity.api.server.idp.common.Constants.GOOGLE_PRIVATE_KEY; + /** - * The factory class for creating instances of FederatedAuthenticatorConfig depending on the definedBy type. - * Returns FederatedAuthenticatorConfig for SYSTEM types and UserDefinedFederatedAuthenticatorConfig for USER types. + * The factory class for building federated authenticator configuration related models. */ public class FederatedAuthenticatorConfigBuilderFactory { - private static FederatedAuthenticatorConfig createFederatedAuthenticatorConfig(Builder builder) + /** + * Builds a FederatedAuthenticatorConfig instance based on the definedBy type for the + * given FederatedAuthenticatorPUTRequest. + * + * @param authenticator FederatedAuthenticatorPUTRequest instance. + * @param definedByType DefinedByType of the authenticator. + * @return FederatedAuthenticatorConfig instance. + * @throws IdentityProviderManagementClientException If an error occurs while building + * the FederatedAuthenticatorConfig. + */ + public static FederatedAuthenticatorConfig build(FederatedAuthenticatorPUTRequest authenticator, String + authenticatorName, DefinedByType definedByType) throws IdentityProviderManagementClientException { + + List properties = Optional.ofNullable(authenticator.getProperties()) + .map(props -> props.stream().map(propertyToInternal).collect(Collectors.toList())) + .orElse(null); + FederatedAuthenticatorConfigBuilderFactory.Config config = + new FederatedAuthenticatorConfigBuilderFactory.Config(authenticatorName, + getDisplayNameOfAuthenticator(authenticatorName), + authenticator.getEndpoint(), properties, authenticator.getIsEnabled(), definedByType); + return FederatedAuthenticatorConfigBuilderFactory.createFederatedAuthenticatorConfig(config); + } + + /** + * Builds a FederatedAuthenticatorConfig instance based on the definedBy type for the given FederatedAuthenticator. + * + * @param authenticator FederatedAuthenticator instance. + * @param definedByType DefinedByType of the authenticator. + * @return FederatedAuthenticator instance. + * @throws IdentityProviderManagementClientException If an error occurs while building the + * FederatedAuthenticatorConfig. + */ + public static FederatedAuthenticatorConfig build(FederatedAuthenticator authenticator, String + authenticatorName, DefinedByType definedByType) throws IdentityProviderManagementClientException { + + List properties = Optional.ofNullable(authenticator.getProperties()) + .map(props -> props.stream().map(propertyToInternal).collect(Collectors.toList())) + .orElse(null); + FederatedAuthenticatorConfigBuilderFactory.Config config = + new FederatedAuthenticatorConfigBuilderFactory.Config(authenticatorName, + getDisplayNameOfAuthenticator(authenticatorName), + authenticator.getEndpoint(), properties, authenticator.getIsEnabled(), definedByType); + + return FederatedAuthenticatorConfigBuilderFactory.createFederatedAuthenticatorConfig(config); + } + + /** + * Builds a FederatedAuthenticatorConfig instance based on the definedBy type for the given + * FederatedAuthenticatorConfig. + * + * @param config FederatedAuthenticatorConfig instance. + * @return FederatedAuthenticator instance. + * @throws IdentityProviderManagementServerException If an error occurs while building the + * FederatedAuthenticator. + */ + public static FederatedAuthenticator build(FederatedAuthenticatorConfig config) + throws IdentityProviderManagementServerException { + + FederatedAuthenticator federatedAuthenticator = new FederatedAuthenticator(); + + federatedAuthenticator.setName(config.getName()); + federatedAuthenticator.setIsEnabled(config.isEnabled()); + + FederatedAuthenticatorConfig federatedAuthenticatorConfig = + ApplicationAuthenticatorService.getInstance().getFederatedAuthenticatorByName( + config.getName()); + if (federatedAuthenticatorConfig != null) { + String[] tags = federatedAuthenticatorConfig.getTags(); + if (ArrayUtils.isNotEmpty(tags)) { + federatedAuthenticator.setTags(Arrays.asList(tags)); + } + } + + if (DefinedByType.SYSTEM == config.getDefinedByType()) { + federatedAuthenticator.setDefinedBy(FederatedAuthenticator.DefinedByEnum.SYSTEM); + List properties = + Arrays.stream(config.getProperties()).map(propertyToExternal).collect(Collectors.toList()); + federatedAuthenticator.setProperties(properties); + } else { + federatedAuthenticator.setDefinedBy(FederatedAuthenticator.DefinedByEnum.USER); + resolveEndpointConfiguration(federatedAuthenticator, config); + } + + return federatedAuthenticator; + } + + private static FederatedAuthenticatorConfig createFederatedAuthenticatorConfig(Config config) throws IdentityProviderManagementClientException { - FederatedAuthenticatorConfig config; - if (DefinedByType.SYSTEM == builder.definedByType) { - config = createSystemDefinedFederatedAuthenticator(builder); + FederatedAuthenticatorConfig federatedAuthenticatorConfig; + if (DefinedByType.SYSTEM == config.definedByType) { + federatedAuthenticatorConfig = createSystemDefinedFederatedAuthenticator(config); } else { - config = createUserDefinedFederatedAuthenticator(builder); + federatedAuthenticatorConfig = createUserDefinedFederatedAuthenticator(config); } - config.setName(builder.authenticatorName); - config.setDisplayName(builder.displayName); - config.setEnabled(builder.isEnabled); + federatedAuthenticatorConfig.setName(config.authenticatorName); + federatedAuthenticatorConfig.setDisplayName(config.displayName); + federatedAuthenticatorConfig.setEnabled(config.isEnabled); - return config; + return federatedAuthenticatorConfig; } private static FederatedAuthenticatorConfig createSystemDefinedFederatedAuthenticator( - Builder builder) throws IdentityProviderManagementClientException { + Config config) throws IdentityProviderManagementClientException { - validateSystemDefinedFederatedAuthenticatorModel(builder); + validateSystemDefinedFederatedAuthenticatorModel(config); FederatedAuthenticatorConfig authConfig = new FederatedAuthenticatorConfig(); authConfig.setDefinedByType(DefinedByType.SYSTEM); - authConfig.setProperties(builder.properties.toArray(new Property[0])); + authConfig.setProperties(config.properties.toArray(new Property[0])); return authConfig; } - private static void validateSystemDefinedFederatedAuthenticatorModel(Builder builder) + private static void validateSystemDefinedFederatedAuthenticatorModel(Config config) throws IdentityProviderManagementClientException { // The System-defined authenticator configs must not have endpoint configurations; throw an error if they do. - if (builder.endpoint != null) { + if (config.endpoint != null) { Constants.ErrorMessage error = Constants.ErrorMessage.ERROR_CODE_ENDPOINT_PROVIDED_FOR_SYSTEM_AUTH; throw new IdentityProviderManagementClientException(error.getCode(), String.format(error.getDescription(), - builder.authenticatorName)); + config.authenticatorName)); } + + validateAuthenticatorProperties(config.authenticatorName, config.properties); } - private static UserDefinedFederatedAuthenticatorConfig createUserDefinedFederatedAuthenticator(Builder builder) + private static UserDefinedFederatedAuthenticatorConfig createUserDefinedFederatedAuthenticator(Config config) throws IdentityProviderManagementClientException { - validateUserDefinedFederatedAuthenticatorModel(builder); + validateUserDefinedFederatedAuthenticatorModel(config); UserDefinedFederatedAuthenticatorConfig authConfig = new UserDefinedFederatedAuthenticatorConfig(); UserDefinedAuthenticatorEndpointConfig.UserDefinedAuthenticatorEndpointConfigBuilder endpointConfigBuilder = new UserDefinedAuthenticatorEndpointConfig.UserDefinedAuthenticatorEndpointConfigBuilder(); - endpointConfigBuilder.uri(builder.endpoint.getUri()); - endpointConfigBuilder.authenticationType(builder.endpoint.getAuthentication().getType().toString()); - endpointConfigBuilder.authenticationProperties(builder.endpoint.getAuthentication().getProperties() + endpointConfigBuilder.uri(config.endpoint.getUri()); + endpointConfigBuilder.authenticationType(config.endpoint.getAuthentication().getType().toString()); + endpointConfigBuilder.authenticationProperties(config.endpoint.getAuthentication().getProperties() .entrySet().stream().collect(Collectors.toMap( Map.Entry::getKey, entry -> entry.getValue().toString()))); authConfig.setEndpointConfig(endpointConfigBuilder.build()); @@ -93,74 +197,238 @@ private static UserDefinedFederatedAuthenticatorConfig createUserDefinedFederate return authConfig; } - private static void validateUserDefinedFederatedAuthenticatorModel(Builder builder) + private static void validateUserDefinedFederatedAuthenticatorModel(Config config) throws IdentityProviderManagementClientException { // The User-defined authenticator configs must not have properties configurations; throw an error if they do. - if (builder.properties != null) { + if (config.properties != null) { Constants.ErrorMessage error = Constants.ErrorMessage.ERROR_CODE_PROPERTIES_PROVIDED_FOR_USER_AUTH; throw new IdentityProviderManagementClientException(error.getCode(), - String.format(error.getDescription(), builder.authenticatorName)); + String.format(error.getDescription(), config.authenticatorName)); } // The User-defined authenticator configs must have endpoint configurations; throw an error if they don't. - if (builder.endpoint == null) { + if (config.endpoint == null) { Constants.ErrorMessage error = Constants.ErrorMessage.ERROR_CODE_NO_ENDPOINT_PROVIDED; throw new IdentityProviderManagementClientException(error.getCode(), - String.format(error.getDescription(), builder.authenticatorName)); + String.format(error.getDescription(), config.authenticatorName)); + } + } + + private static void validateAuthenticatorProperties(String authenticatorName, List properties) + throws IdentityProviderManagementClientException { + + if (properties == null) { + return; + } + + if (IdentityApplicationConstants.Authenticator.SAML2SSO.FED_AUTH_NAME.equals(authenticatorName)) { + validateSamlMetadata(properties); + } + if (IdentityApplicationConstants.Authenticator.OIDC.FED_AUTH_NAME.equals(authenticatorName)) { + validateDuplicateOpenIDConnectScopes(properties); + validateDefaultOpenIDConnectScopes(properties); + } + + if (!areAllDistinct(properties)) { + Constants.ErrorMessage error = Constants.ErrorMessage.ERROR_CODE_INVALID_INPUT; + throw new IdentityProviderManagementClientException(error.getCode(), error.getDescription()); } } /** - * Builder class to build FederatedAuthenticatorConfig. + * If selectMode property is set as saml metadata file configuration mode, this function validates whether a + * valid base-64 encoded SAML metadata file content is provided with the property key 'meta_data_saml'. If found, + * it will decode the file content and update the value of 'meta_data_saml' property with decoded content. + * + * @param samlAuthenticatorProperties Authenticator properties of SAML authenticator. */ - public static class Builder { - private DefinedByType definedByType; - private String authenticatorName; - private String displayName; - private Endpoint endpoint; - private List properties; - private Boolean isEnabled; - - public Builder definedByType(DefinedByType definedByType) { + private static void validateSamlMetadata(List samlAuthenticatorProperties) + throws IdentityProviderManagementClientException { - this.definedByType = definedByType; - return this; + if (samlAuthenticatorProperties != null) { + for (Property property : samlAuthenticatorProperties) { + + if (Constants.SELECT_MODE.equals(property.getName()) && + Constants.SELECT_MODE_METADATA.equals(property.getValue())) { + // SAML metadata file configuration has been selected. Hence we need to validate whether valid SAML + // metadata (property with key = 'meta_data_saml') is sent. + + boolean validMetadataFound = false; + String encodedData = null; + int positionOfMetadataKey = -1; + + for (int i = 0; i < samlAuthenticatorProperties.size(); i++) { + if (Constants.META_DATA_SAML.equals(samlAuthenticatorProperties.get(i).getName()) && + StringUtils.isNotBlank + (samlAuthenticatorProperties.get(i).getValue())) { + validMetadataFound = true; + encodedData = samlAuthenticatorProperties.get(i).getValue(); + positionOfMetadataKey = i; + break; + } + } + if (validMetadataFound) { + String metadata = new String(Base64.getDecoder().decode(encodedData), (StandardCharsets.UTF_8)); + // Add decoded data to property list. + Property metadataProperty = samlAuthenticatorProperties.get(positionOfMetadataKey); + metadataProperty.setValue(metadata); + samlAuthenticatorProperties.set(positionOfMetadataKey, metadataProperty); + } else { + Constants.ErrorMessage error = Constants.ErrorMessage.ERROR_CODE_INVALID_SAML_METADATA; + throw new IdentityProviderManagementClientException(error.getCode(), error.getDescription()); + } + } + } } + } - public Builder authenticatorName(String authenticatorName) { + /** + * Verify if scopes have not been set in both Scopes field and Additional Query Parameters field + * + * @param oidcAuthenticatorProperties Authenticator properties of OIDC authenticator. + */ + private static void validateDuplicateOpenIDConnectScopes(List oidcAuthenticatorProperties) + throws IdentityProviderManagementClientException { - this.authenticatorName = authenticatorName; - return this; + if (oidcAuthenticatorProperties != null) { + boolean scopesFieldFilled = false; + boolean queryParamsScopesFilled = false; + for (Property oidcAuthenticatorProperty : oidcAuthenticatorProperties) { + if (IdentityApplicationConstants.Authenticator.OIDC.SCOPES.equals(oidcAuthenticatorProperty.getName()) + && StringUtils.isNotBlank(oidcAuthenticatorProperty.getValue())) { + scopesFieldFilled = true; + } + if (IdentityApplicationConstants.Authenticator.OIDC.QUERY_PARAMS.equals + (oidcAuthenticatorProperty.getName()) + && oidcAuthenticatorProperty.getValue().contains("scope=")) { + queryParamsScopesFilled = true; + } + } + if (scopesFieldFilled && queryParamsScopesFilled) { + Constants.ErrorMessage error = Constants.ErrorMessage.ERROR_CODE_DUPLICATE_OIDC_SCOPES; + throw new IdentityProviderManagementClientException(error.getCode(), error.getDescription()); + } } + } - public Builder displayName(String displayName) { + /** + * Verify if scopes contain `openid`. + * + * @param oidcAuthenticatorProperties Authenticator properties of OIDC authenticator. + */ + private static void validateDefaultOpenIDConnectScopes(List oidcAuthenticatorProperties) + throws IdentityProviderManagementClientException { - this.displayName = displayName; - return this; + if (oidcAuthenticatorProperties != null) { + for (Property oidcAuthenticatorProperty : oidcAuthenticatorProperties) { + if (IdentityApplicationConstants.Authenticator.OIDC.SCOPES.equals( + oidcAuthenticatorProperty.getName())) { + String scopes = oidcAuthenticatorProperty.getValue(); + if (StringUtils.isNotBlank(scopes) && !scopes.contains("openid")) { + Constants.ErrorMessage error = Constants.ErrorMessage.ERROR_CODE_INVALID_OIDC_SCOPES; + throw new IdentityProviderManagementClientException(error.getCode(), error.getDescription()); + } + } + } } + } - public Builder endpoint(Endpoint endpoint) { + static boolean areAllDistinct(List properties) { + return properties.stream() + .map(Property::getName) + .distinct().count() == properties.size(); + } - this.endpoint = endpoint; - return this; + private static Function propertyToInternal + = apiProperty -> { + + Property property = new Property(); + property.setName(apiProperty.getKey()); + property.setValue(apiProperty.getValue()); + if (StringUtils.equals(GOOGLE_PRIVATE_KEY, apiProperty.getKey())) { + property.setType(IdentityApplicationConstants.ConfigElements.PROPERTY_TYPE_BLOB); } + return property; + }; - public Builder properties(List properties) { + private static Function propertyToExternal + = property -> { - this.properties = properties; - return this; + org.wso2.carbon.identity.api.server.idp.v1.model.Property apiProperty = new org.wso2.carbon.identity.api + .server.idp.v1.model.Property(); + apiProperty.setKey(property.getName()); + apiProperty.setValue(property.getValue()); + return apiProperty; + }; + + /** + * Returns the 'DisplayName' property of the federated authenticator identified by authenticator name. + * + * @param authenticatorName Federated authenticator name. + * @return Display name of authenticator. + */ + private static String getDisplayNameOfAuthenticator(String authenticatorName) + throws IdentityProviderManagementClientException { + + try { + FederatedAuthenticatorConfig[] authenticatorConfigs = + IdentityProviderServiceHolder.getIdentityProviderManager() + .getAllFederatedAuthenticators(); + for (FederatedAuthenticatorConfig config : authenticatorConfigs) { + + if (StringUtils.equals(config.getName(), authenticatorName)) { + return config.getDisplayName(); + } + } + } catch (IdentityProviderManagementException e) { + Constants.ErrorMessage error = Constants.ErrorMessage.ERROR_CODE_ERROR_ADDING_IDP; + throw new IdentityProviderManagementClientException(error.getCode(), error.getDescription()); } + return null; + } - public Builder enabled(Boolean enabled) { + private static void resolveEndpointConfiguration(FederatedAuthenticator authenticator, + FederatedAuthenticatorConfig config) throws IdentityProviderManagementServerException { - isEnabled = enabled; - return this; + try { + UserDefinedFederatedAuthenticatorConfig userDefinedConfig = + (UserDefinedFederatedAuthenticatorConfig) config; + UserDefinedAuthenticatorEndpointConfig endpointConfig = userDefinedConfig.getEndpointConfig(); + + AuthenticationType authenticationType = new AuthenticationType(); + authenticationType.setType(AuthenticationType.TypeEnum.fromValue(endpointConfig.getEndpointConfig() + .getAuthentication().getType().toString())); + + Endpoint endpoint = new Endpoint(); + endpoint.setUri(endpointConfig.getEndpointConfig().getUri()); + authenticator.setEndpoint(endpoint); + } catch (ClassCastException e) { + throw new IdentityProviderManagementServerException(String.format("Error occurred while resolving" + + " endpoint configuration of the authenticator %s.", authenticator.getName()), e); } + } - public FederatedAuthenticatorConfig build() throws IdentityProviderManagementClientException { + /** + * Config class to build FederatedAuthenticatorConfig. + */ + public static class Config { + private final DefinedByType definedByType; + private final String authenticatorName; + private final String displayName; + private final Endpoint endpoint; + private final List properties; + private final Boolean isEnabled; + + public Config(String authenticatorName, String displayName, Endpoint endpoint, + List properties, Boolean isEnabled, DefinedByType definedByType) { - return FederatedAuthenticatorConfigBuilderFactory.createFederatedAuthenticatorConfig(this); + this.authenticatorName = authenticatorName; + this.displayName = displayName; + this.endpoint = endpoint; + this.properties = properties; + this.isEnabled = isEnabled; + this.definedByType = definedByType; } } } diff --git a/pom.xml b/pom.xml index 8f35524226..76792cd84a 100644 --- a/pom.xml +++ b/pom.xml @@ -809,7 +809,7 @@ 1.4 1.2.4 1.11.11 - 7.5.117 + 7.5.121-SNAPSHOT 3.0.5 1.12.0 **/gen/**/* From 455d408128d1d2c2c6750a3669e363e9ba565bea Mon Sep 17 00:00:00 2001 From: Thisara-Welmilla Date: Tue, 19 Nov 2024 08:44:56 +0530 Subject: [PATCH 07/10] Update APIs to support custom authentication management. --- .../api/server/idp/common/Constants.java | 2 ++ .../v1/core/ServerIdpManagementService.java | 4 +++ ...atedAuthenticatorConfigBuilderFactory.java | 28 +++++++++++-------- 3 files changed, 23 insertions(+), 11 deletions(-) diff --git a/components/org.wso2.carbon.identity.api.server.idp/org.wso2.carbon.identity.api.server.idp.common/src/main/java/org/wso2/carbon/identity/api/server/idp/common/Constants.java b/components/org.wso2.carbon.identity.api.server.idp/org.wso2.carbon.identity.api.server.idp.common/src/main/java/org/wso2/carbon/identity/api/server/idp/common/Constants.java index d578b8f918..fe30c0eb24 100644 --- a/components/org.wso2.carbon.identity.api.server.idp/org.wso2.carbon.identity.api.server.idp.common/src/main/java/org/wso2/carbon/identity/api/server/idp/common/Constants.java +++ b/components/org.wso2.carbon.identity.api.server.idp/org.wso2.carbon.identity.api.server.idp.common/src/main/java/org/wso2/carbon/identity/api/server/idp/common/Constants.java @@ -158,6 +158,8 @@ public enum ErrorMessage { "Unable to decode the provided authenticator ID %s."), ERROR_CODE_NO_SYSTEM_AUTHENTICATOR_FOUND("60043", "No system authenticator found.", "No system authenticator found for the provided authenticator Id %s."), + ERROR_COED_MULTIPLE_USER_DEFINED_AUTHENTICATORS_FOUND("60044", "Multiple authenticators found.", + "Multiple user defined authenticators are not allowed."), // Server Error starting from 650xx. ERROR_CODE_ERROR_ADDING_IDP("65002", diff --git a/components/org.wso2.carbon.identity.api.server.idp/org.wso2.carbon.identity.api.server.idp.v1/src/main/java/org/wso2/carbon/identity/api/server/idp/v1/core/ServerIdpManagementService.java b/components/org.wso2.carbon.identity.api.server.idp/org.wso2.carbon.identity.api.server.idp.v1/src/main/java/org/wso2/carbon/identity/api/server/idp/v1/core/ServerIdpManagementService.java index 425f298f00..50ac07fe64 100644 --- a/components/org.wso2.carbon.identity.api.server.idp/org.wso2.carbon.identity.api.server.idp.v1/src/main/java/org/wso2/carbon/identity/api/server/idp/v1/core/ServerIdpManagementService.java +++ b/components/org.wso2.carbon.identity.api.server.idp/org.wso2.carbon.identity.api.server.idp.v1/src/main/java/org/wso2/carbon/identity/api/server/idp/v1/core/ServerIdpManagementService.java @@ -1779,6 +1779,10 @@ private void updateFederatedAuthenticatorConfig(IdentityProvider idp, FederatedA } else { definedByType = resolveDefinedByTypeToUpdateFederatedAuthenticator(authenticatorName); } + if (definedByType == DefinedByType.USER && federatedAuthenticators.size() > 1) { + throw handleException(Response.Status.BAD_REQUEST, + Constants.ErrorMessage.ERROR_COED_MULTIPLE_USER_DEFINED_AUTHENTICATORS_FOUND, null); + } FederatedAuthenticatorConfig authConfig = FederatedAuthenticatorConfigBuilderFactory.build( authenticator, authenticatorName, definedByType); diff --git a/components/org.wso2.carbon.identity.api.server.idp/org.wso2.carbon.identity.api.server.idp.v1/src/main/java/org/wso2/carbon/identity/api/server/idp/v1/impl/FederatedAuthenticatorConfigBuilderFactory.java b/components/org.wso2.carbon.identity.api.server.idp/org.wso2.carbon.identity.api.server.idp.v1/src/main/java/org/wso2/carbon/identity/api/server/idp/v1/impl/FederatedAuthenticatorConfigBuilderFactory.java index 7f2d7800a6..83e87d9628 100644 --- a/components/org.wso2.carbon.identity.api.server.idp/org.wso2.carbon.identity.api.server.idp.v1/src/main/java/org/wso2/carbon/identity/api/server/idp/v1/impl/FederatedAuthenticatorConfigBuilderFactory.java +++ b/components/org.wso2.carbon.identity.api.server.idp/org.wso2.carbon.identity.api.server.idp.v1/src/main/java/org/wso2/carbon/identity/api/server/idp/v1/impl/FederatedAuthenticatorConfigBuilderFactory.java @@ -42,6 +42,7 @@ import java.util.Base64; import java.util.List; import java.util.Map; +import java.util.NoSuchElementException; import java.util.Optional; import java.util.function.Function; import java.util.stream.Collectors; @@ -184,17 +185,22 @@ private static UserDefinedFederatedAuthenticatorConfig createUserDefinedFederate validateUserDefinedFederatedAuthenticatorModel(config); - UserDefinedFederatedAuthenticatorConfig authConfig = new UserDefinedFederatedAuthenticatorConfig(); - UserDefinedAuthenticatorEndpointConfig.UserDefinedAuthenticatorEndpointConfigBuilder endpointConfigBuilder = - new UserDefinedAuthenticatorEndpointConfig.UserDefinedAuthenticatorEndpointConfigBuilder(); - endpointConfigBuilder.uri(config.endpoint.getUri()); - endpointConfigBuilder.authenticationType(config.endpoint.getAuthentication().getType().toString()); - endpointConfigBuilder.authenticationProperties(config.endpoint.getAuthentication().getProperties() - .entrySet().stream().collect(Collectors.toMap( - Map.Entry::getKey, entry -> entry.getValue().toString()))); - authConfig.setEndpointConfig(endpointConfigBuilder.build()); - - return authConfig; + try { + UserDefinedFederatedAuthenticatorConfig authConfig = new UserDefinedFederatedAuthenticatorConfig(); + UserDefinedAuthenticatorEndpointConfig.UserDefinedAuthenticatorEndpointConfigBuilder endpointConfigBuilder = + new UserDefinedAuthenticatorEndpointConfig.UserDefinedAuthenticatorEndpointConfigBuilder(); + endpointConfigBuilder.uri(config.endpoint.getUri()); + endpointConfigBuilder.authenticationType(config.endpoint.getAuthentication().getType().toString()); + endpointConfigBuilder.authenticationProperties(config.endpoint.getAuthentication().getProperties() + .entrySet().stream().collect(Collectors.toMap( + Map.Entry::getKey, entry -> entry.getValue().toString()))); + authConfig.setEndpointConfig(endpointConfigBuilder.build()); + + return authConfig; + } catch (NoSuchElementException e) { + throw new IdentityProviderManagementClientException(Constants.ErrorMessage + .ERROR_CODE_INVALID_INPUT.getCode(), e.getMessage()); + } } private static void validateUserDefinedFederatedAuthenticatorModel(Config config) From b33ef9f30ae0264e916edad887500f0ebe3506a2 Mon Sep 17 00:00:00 2001 From: Thisara-Welmilla Date: Wed, 27 Nov 2024 10:05:09 +0530 Subject: [PATCH 08/10] Fix response for user defined auth. --- .../idp/v1/impl/FederatedAuthenticatorConfigBuilderFactory.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/components/org.wso2.carbon.identity.api.server.idp/org.wso2.carbon.identity.api.server.idp.v1/src/main/java/org/wso2/carbon/identity/api/server/idp/v1/impl/FederatedAuthenticatorConfigBuilderFactory.java b/components/org.wso2.carbon.identity.api.server.idp/org.wso2.carbon.identity.api.server.idp.v1/src/main/java/org/wso2/carbon/identity/api/server/idp/v1/impl/FederatedAuthenticatorConfigBuilderFactory.java index 83e87d9628..b30cc42281 100644 --- a/components/org.wso2.carbon.identity.api.server.idp/org.wso2.carbon.identity.api.server.idp.v1/src/main/java/org/wso2/carbon/identity/api/server/idp/v1/impl/FederatedAuthenticatorConfigBuilderFactory.java +++ b/components/org.wso2.carbon.identity.api.server.idp/org.wso2.carbon.identity.api.server.idp.v1/src/main/java/org/wso2/carbon/identity/api/server/idp/v1/impl/FederatedAuthenticatorConfigBuilderFactory.java @@ -405,9 +405,11 @@ private static void resolveEndpointConfiguration(FederatedAuthenticator authenti AuthenticationType authenticationType = new AuthenticationType(); authenticationType.setType(AuthenticationType.TypeEnum.fromValue(endpointConfig.getEndpointConfig() .getAuthentication().getType().toString())); + authenticationType.setProperties(null); Endpoint endpoint = new Endpoint(); endpoint.setUri(endpointConfig.getEndpointConfig().getUri()); + endpoint.setAuthentication(authenticationType); authenticator.setEndpoint(endpoint); } catch (ClassCastException e) { throw new IdentityProviderManagementServerException(String.format("Error occurred while resolving" + From 8e8632fd998eefc117cce5fa015178e48d7f83b5 Mon Sep 17 00:00:00 2001 From: Thisara-Welmilla Date: Thu, 28 Nov 2024 15:46:20 +0530 Subject: [PATCH 09/10] Update APIs to support custom authentication management. --- .../api/server/idp/v1/model/AuthenticationType.java | 9 +++++---- .../src/main/resources/idp.yaml | 1 - 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/components/org.wso2.carbon.identity.api.server.idp/org.wso2.carbon.identity.api.server.idp.v1/src/gen/java/org/wso2/carbon/identity/api/server/idp/v1/model/AuthenticationType.java b/components/org.wso2.carbon.identity.api.server.idp/org.wso2.carbon.identity.api.server.idp.v1/src/gen/java/org/wso2/carbon/identity/api/server/idp/v1/model/AuthenticationType.java index 1b2660df61..92dfec771b 100644 --- a/components/org.wso2.carbon.identity.api.server.idp/org.wso2.carbon.identity.api.server.idp.v1/src/gen/java/org/wso2/carbon/identity/api/server/idp/v1/model/AuthenticationType.java +++ b/components/org.wso2.carbon.identity.api.server.idp/org.wso2.carbon.identity.api.server.idp.v1/src/gen/java/org/wso2/carbon/identity/api/server/idp/v1/model/AuthenticationType.java @@ -69,7 +69,7 @@ public static TypeEnum fromValue(String value) { } private TypeEnum type; - private Map properties = new HashMap<>(); + private Map properties = null; /** @@ -100,11 +100,9 @@ public AuthenticationType properties(Map properties) { return this; } - @ApiModelProperty(example = "{\"username\":\"auth_username\",\"password\":\"auth_password\"}", required = true, value = "") + @ApiModelProperty(example = "{\"username\":\"auth_username\",\"password\":\"auth_password\"}", value = "") @JsonProperty("properties") @Valid - @NotNull(message = "Property properties cannot be null.") - public Map getProperties() { return properties; } @@ -114,6 +112,9 @@ public void setProperties(Map properties) { public AuthenticationType putPropertiesItem(String key, Object propertiesItem) { + if (this.properties == null) { + this.properties = new HashMap<>(); + } this.properties.put(key, propertiesItem); return this; } diff --git a/components/org.wso2.carbon.identity.api.server.idp/org.wso2.carbon.identity.api.server.idp.v1/src/main/resources/idp.yaml b/components/org.wso2.carbon.identity.api.server.idp/org.wso2.carbon.identity.api.server.idp.v1/src/main/resources/idp.yaml index 1e62cdb2d8..e05b96d189 100644 --- a/components/org.wso2.carbon.identity.api.server.idp/org.wso2.carbon.identity.api.server.idp.v1/src/main/resources/idp.yaml +++ b/components/org.wso2.carbon.identity.api.server.idp/org.wso2.carbon.identity.api.server.idp.v1/src/main/resources/idp.yaml @@ -2895,7 +2895,6 @@ components: type: object required: - type - - properties properties: type: type: string From 9506720d76dfd29786aa4e5a0bef192164e6fde1 Mon Sep 17 00:00:00 2001 From: Thisara-Welmilla Date: Mon, 2 Dec 2024 18:06:38 +0530 Subject: [PATCH 10/10] Update APIs to support custom authentication management. --- .../api/server/idp/v1/core/ServerIdpManagementService.java | 2 ++ .../idp/v1/impl/FederatedAuthenticatorConfigBuilderFactory.java | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/components/org.wso2.carbon.identity.api.server.idp/org.wso2.carbon.identity.api.server.idp.v1/src/main/java/org/wso2/carbon/identity/api/server/idp/v1/core/ServerIdpManagementService.java b/components/org.wso2.carbon.identity.api.server.idp/org.wso2.carbon.identity.api.server.idp.v1/src/main/java/org/wso2/carbon/identity/api/server/idp/v1/core/ServerIdpManagementService.java index 50ac07fe64..63597d12e3 100644 --- a/components/org.wso2.carbon.identity.api.server.idp/org.wso2.carbon.identity.api.server.idp.v1/src/main/java/org/wso2/carbon/identity/api/server/idp/v1/core/ServerIdpManagementService.java +++ b/components/org.wso2.carbon.identity.api.server.idp/org.wso2.carbon.identity.api.server.idp.v1/src/main/java/org/wso2/carbon/identity/api/server/idp/v1/core/ServerIdpManagementService.java @@ -596,6 +596,8 @@ public FederatedAuthenticatorListResponse getFederatedAuthenticators(String idpI listItem.setAuthenticatorId(fedAuthId); listItem.setName(config.getName()); listItem.setIsEnabled(config.isEnabled()); + listItem.setDefinedBy( + FederatedAuthenticatorListItem.DefinedByEnum.valueOf(config.getDefinedByType().toString())); FederatedAuthenticatorConfig federatedAuthenticatorConfig = ApplicationAuthenticatorService.getInstance().getFederatedAuthenticatorByName( config.getName()); diff --git a/components/org.wso2.carbon.identity.api.server.idp/org.wso2.carbon.identity.api.server.idp.v1/src/main/java/org/wso2/carbon/identity/api/server/idp/v1/impl/FederatedAuthenticatorConfigBuilderFactory.java b/components/org.wso2.carbon.identity.api.server.idp/org.wso2.carbon.identity.api.server.idp.v1/src/main/java/org/wso2/carbon/identity/api/server/idp/v1/impl/FederatedAuthenticatorConfigBuilderFactory.java index b30cc42281..2d8b8c9906 100644 --- a/components/org.wso2.carbon.identity.api.server.idp/org.wso2.carbon.identity.api.server.idp.v1/src/main/java/org/wso2/carbon/identity/api/server/idp/v1/impl/FederatedAuthenticatorConfigBuilderFactory.java +++ b/components/org.wso2.carbon.identity.api.server.idp/org.wso2.carbon.identity.api.server.idp.v1/src/main/java/org/wso2/carbon/identity/api/server/idp/v1/impl/FederatedAuthenticatorConfigBuilderFactory.java @@ -197,7 +197,7 @@ private static UserDefinedFederatedAuthenticatorConfig createUserDefinedFederate authConfig.setEndpointConfig(endpointConfigBuilder.build()); return authConfig; - } catch (NoSuchElementException e) { + } catch (NoSuchElementException | IllegalArgumentException e) { throw new IdentityProviderManagementClientException(Constants.ErrorMessage .ERROR_CODE_INVALID_INPUT.getCode(), e.getMessage()); }