diff --git a/components/org.wso2.carbon.identity.api.server.action.management/org.wso2.carbon.identity.api.server.action.management.v1/pom.xml b/components/org.wso2.carbon.identity.api.server.action.management/org.wso2.carbon.identity.api.server.action.management.v1/pom.xml index 2bbd2e1b45..22105833ae 100644 --- a/components/org.wso2.carbon.identity.api.server.action.management/org.wso2.carbon.identity.api.server.action.management.v1/pom.xml +++ b/components/org.wso2.carbon.identity.api.server.action.management/org.wso2.carbon.identity.api.server.action.management.v1/pom.xml @@ -111,6 +111,12 @@ org.wso2.carbon.identity.server.api org.wso2.carbon.identity.api.server.action.management.common + + org.wso2.carbon.identity.framework + org.wso2.carbon.identity.flow.extensions + ${carbon.identity.framework.version} + provided + diff --git a/components/org.wso2.carbon.identity.api.server.action.management/org.wso2.carbon.identity.api.server.action.management.v1/src/extend/java/org/wso2/carbon/identity/api/server/action/management/v1/AccessConfigModel.java b/components/org.wso2.carbon.identity.api.server.action.management/org.wso2.carbon.identity.api.server.action.management.v1/src/extend/java/org/wso2/carbon/identity/api/server/action/management/v1/AccessConfigModel.java new file mode 100644 index 0000000000..0fcce1ac5c --- /dev/null +++ b/components/org.wso2.carbon.identity.api.server.action.management/org.wso2.carbon.identity.api.server.action.management.v1/src/extend/java/org/wso2/carbon/identity/api/server/action/management/v1/AccessConfigModel.java @@ -0,0 +1,138 @@ +/* + * Copyright (c) 2025, 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.action.management.v1; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.annotations.ApiModelProperty; + +import java.util.List; +import java.util.Objects; + +import javax.validation.Valid; + +/** + * Access Configuration model for In-Flow Extension actions. + * Defines what context data is exposed and what operations are allowed. + * + *

The {@code expose} field accepts either plain strings (path prefixes) or objects with + * {@code path} and {@code encrypted} properties. When strings are provided, encryption + * defaults to {@code false}.

+ * + *

Example:

+ *
{@code
+ * {
+ *   "expose": [
+ *     "/user/userId",
+ *     { "path": "/user/claims/", "encrypted": true },
+ *     { "path": "/user/credentials/password", "encrypted": true },
+ *     "/properties/"
+ *   ],
+ *   "modify": [
+ *     "/properties/riskScore",
+ *     { "path": "/user/claims/email", "encrypted": true }
+ *   ]
+ * }
+ * }
+ */ +public class AccessConfigModel { + + private List expose; + private List modify; + + public AccessConfigModel() { + // Default constructor required for Jackson + } + + public AccessConfigModel expose(List expose) { + + this.expose = expose; + return this; + } + + @ApiModelProperty() + @JsonProperty("expose") + @Valid + public List getExpose() { + + return expose; + } + + public void setExpose(List expose) { + + this.expose = expose; + } + + public AccessConfigModel modify(List modify) { + + this.modify = modify; + return this; + } + + @ApiModelProperty() + @JsonProperty("modify") + @Valid + public List getModify() { + + return modify; + } + + public void setModify(List modify) { + + this.modify = modify; + } + + @Override + public boolean equals(java.lang.Object o) { + + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + AccessConfigModel that = (AccessConfigModel) o; + return Objects.equals(this.expose, that.expose) && + Objects.equals(this.modify, that.modify); + } + + @Override + public int hashCode() { + + return Objects.hash(expose, modify); + } + + @Override + public String toString() { + + StringBuilder sb = new StringBuilder(); + sb.append("class AccessConfigModel {\n"); + sb.append(" expose: ").append(toIndentedString(expose)).append("\n"); + sb.append(" modify: ").append(toIndentedString(modify)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + 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.action.management/org.wso2.carbon.identity.api.server.action.management.v1/src/extend/java/org/wso2/carbon/identity/api/server/action/management/v1/EncryptionModel.java b/components/org.wso2.carbon.identity.api.server.action.management/org.wso2.carbon.identity.api.server.action.management.v1/src/extend/java/org/wso2/carbon/identity/api/server/action/management/v1/EncryptionModel.java new file mode 100644 index 0000000000..9ddaf2d4c5 --- /dev/null +++ b/components/org.wso2.carbon.identity.api.server.action.management/org.wso2.carbon.identity.api.server.action.management.v1/src/extend/java/org/wso2/carbon/identity/api/server/action/management/v1/EncryptionModel.java @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2025, 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.action.management.v1; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.annotations.ApiModelProperty; + +import java.util.Objects; + +import javax.validation.Valid; + +/** + * Encryption configuration model for In-Flow Extension actions. + * Holds the external service's certificate used for JWE encryption of sensitive data. + */ +public class EncryptionModel { + + private String certificate; + + public EncryptionModel() { + // Default constructor required for Jackson + } + + public EncryptionModel certificate(String certificate) { + + this.certificate = certificate; + return this; + } + + @ApiModelProperty() + @JsonProperty("certificate") + @Valid + public String getCertificate() { + + return certificate; + } + + public void setCertificate(String certificate) { + + this.certificate = certificate; + } + + @Override + public boolean equals(java.lang.Object o) { + + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + EncryptionModel that = (EncryptionModel) o; + return Objects.equals(this.certificate, that.certificate); + } + + @Override + public int hashCode() { + + return Objects.hash(certificate); + } + + @Override + public String toString() { + + StringBuilder sb = new StringBuilder(); + sb.append("class EncryptionModel {\n"); + sb.append(" certificate: ").append(toIndentedString(certificate)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + 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.action.management/org.wso2.carbon.identity.api.server.action.management.v1/src/extend/java/org/wso2/carbon/identity/api/server/action/management/v1/InFlowExtensionActionModel.java b/components/org.wso2.carbon.identity.api.server.action.management/org.wso2.carbon.identity.api.server.action.management.v1/src/extend/java/org/wso2/carbon/identity/api/server/action/management/v1/InFlowExtensionActionModel.java new file mode 100644 index 0000000000..fcb3d088d0 --- /dev/null +++ b/components/org.wso2.carbon.identity.api.server.action.management/org.wso2.carbon.identity.api.server.action.management.v1/src/extend/java/org/wso2/carbon/identity/api/server/action/management/v1/InFlowExtensionActionModel.java @@ -0,0 +1,154 @@ +/* + * Copyright (c) 2025, 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.action.management.v1; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.annotations.ApiModelProperty; + +import java.util.Objects; + +import javax.validation.Valid; + +/** + * In-Flow Extension Action Model. + * Extends the base ActionModel with an access configuration. + */ +public class InFlowExtensionActionModel extends ActionModel { + + private AccessConfigModel accessConfig; + private EncryptionModel encryption; + private String iconUrl; + + public InFlowExtensionActionModel() { + // Default constructor required for Jackson + } + + public InFlowExtensionActionModel(ActionModel actionModel) { + + setName(actionModel.getName()); + setDescription(actionModel.getDescription()); + setEndpoint(actionModel.getEndpoint()); + setRule(actionModel.getRule()); + } + + public InFlowExtensionActionModel accessConfig(AccessConfigModel accessConfig) { + + this.accessConfig = accessConfig; + return this; + } + + @ApiModelProperty() + @JsonProperty("accessConfig") + @Valid + public AccessConfigModel getAccessConfig() { + + return accessConfig; + } + + public void setAccessConfig(AccessConfigModel accessConfig) { + + this.accessConfig = accessConfig; + } + + public InFlowExtensionActionModel encryption(EncryptionModel encryption) { + + this.encryption = encryption; + return this; + } + + @ApiModelProperty() + @JsonProperty("encryption") + @Valid + public EncryptionModel getEncryption() { + + return encryption; + } + + public void setEncryption(EncryptionModel encryption) { + + this.encryption = encryption; + } + + public InFlowExtensionActionModel iconUrl(String iconUrl) { + + this.iconUrl = iconUrl; + return this; + } + + @ApiModelProperty() + @JsonProperty("iconUrl") + public String getIconUrl() { + + return iconUrl; + } + + public void setIconUrl(String iconUrl) { + + this.iconUrl = iconUrl; + } + + @Override + public boolean equals(java.lang.Object o) { + + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + InFlowExtensionActionModel actionModel = (InFlowExtensionActionModel) o; + return Objects.equals(this.getName(), actionModel.getName()) && + Objects.equals(this.getDescription(), actionModel.getDescription()) && + Objects.equals(this.getEndpoint(), actionModel.getEndpoint()) && + Objects.equals(this.accessConfig, actionModel.accessConfig) && + Objects.equals(this.encryption, actionModel.encryption) && + Objects.equals(this.iconUrl, actionModel.iconUrl) && + Objects.equals(this.getRule(), actionModel.getRule()); + } + + @Override + public int hashCode() { + + return Objects.hash(getName(), getDescription(), getEndpoint(), accessConfig, encryption, iconUrl, getRule()); + } + + @Override + public String toString() { + + StringBuilder sb = new StringBuilder(); + sb.append("class InFlowExtensionActionModel {\n"); + sb.append(" name: ").append(toIndentedString(getName())).append("\n"); + sb.append(" description: ").append(toIndentedString(getDescription())).append("\n"); + sb.append(" endpoint: ").append(toIndentedString(getEndpoint())).append("\n"); + sb.append(" accessConfig: ").append(toIndentedString(accessConfig)).append("\n"); + sb.append(" encryption: ").append(toIndentedString(encryption)).append("\n"); + sb.append(" iconUrl: ").append(toIndentedString(iconUrl)).append("\n"); + sb.append(" rule: ").append(toIndentedString(getRule())).append("\n"); + sb.append("}"); + return sb.toString(); + } + + 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.action.management/org.wso2.carbon.identity.api.server.action.management.v1/src/extend/java/org/wso2/carbon/identity/api/server/action/management/v1/InFlowExtensionActionResponse.java b/components/org.wso2.carbon.identity.api.server.action.management/org.wso2.carbon.identity.api.server.action.management.v1/src/extend/java/org/wso2/carbon/identity/api/server/action/management/v1/InFlowExtensionActionResponse.java new file mode 100644 index 0000000000..0d0597b8f9 --- /dev/null +++ b/components/org.wso2.carbon.identity.api.server.action.management/org.wso2.carbon.identity.api.server.action.management.v1/src/extend/java/org/wso2/carbon/identity/api/server/action/management/v1/InFlowExtensionActionResponse.java @@ -0,0 +1,186 @@ +/* + * Copyright (c) 2025, 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.action.management.v1; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.annotations.ApiModelProperty; + +import java.util.Map; +import java.util.Objects; + +import javax.validation.Valid; + +/** + * In-Flow Extension Action Response. + * Extends the base ActionResponse with an access configuration. + */ +public class InFlowExtensionActionResponse extends ActionResponse { + + private AccessConfigModel accessConfig; + private EncryptionModel encryption; + private String iconUrl; + private Map flowTypeOverrides; + + public InFlowExtensionActionResponse(ActionResponse actionResponse) { + + setId(actionResponse.getId()); + setType(actionResponse.getType()); + setName(actionResponse.getName()); + setDescription(actionResponse.getDescription()); + setStatus(actionResponse.getStatus()); + setVersion(actionResponse.getVersion()); + setCreatedAt(actionResponse.getCreatedAt()); + setUpdatedAt(actionResponse.getUpdatedAt()); + setEndpoint(actionResponse.getEndpoint()); + setRule(actionResponse.getRule()); + } + + public InFlowExtensionActionResponse accessConfig(AccessConfigModel accessConfig) { + + this.accessConfig = accessConfig; + return this; + } + + @ApiModelProperty() + @JsonProperty("accessConfig") + @Valid + public AccessConfigModel getAccessConfig() { + + return accessConfig; + } + + public void setAccessConfig(AccessConfigModel accessConfig) { + + this.accessConfig = accessConfig; + } + + public InFlowExtensionActionResponse encryption(EncryptionModel encryption) { + + this.encryption = encryption; + return this; + } + + @ApiModelProperty() + @JsonProperty("encryption") + @Valid + public EncryptionModel getEncryption() { + + return encryption; + } + + public void setEncryption(EncryptionModel encryption) { + + this.encryption = encryption; + } + + public InFlowExtensionActionResponse iconUrl(String iconUrl) { + + this.iconUrl = iconUrl; + return this; + } + + @ApiModelProperty() + @JsonProperty("iconUrl") + public String getIconUrl() { + + return iconUrl; + } + + public void setIconUrl(String iconUrl) { + + this.iconUrl = iconUrl; + } + + public InFlowExtensionActionResponse flowTypeOverrides(Map flowTypeOverrides) { + + this.flowTypeOverrides = flowTypeOverrides; + return this; + } + + @ApiModelProperty() + @JsonProperty("flowTypeOverrides") + @Valid + public Map getFlowTypeOverrides() { + + return flowTypeOverrides; + } + + public void setFlowTypeOverrides(Map flowTypeOverrides) { + + this.flowTypeOverrides = flowTypeOverrides; + } + + @Override + public boolean equals(java.lang.Object o) { + + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + InFlowExtensionActionResponse that = (InFlowExtensionActionResponse) o; + return Objects.equals(this.getId(), that.getId()) && + Objects.equals(this.getType(), that.getType()) && + Objects.equals(this.getName(), that.getName()) && + Objects.equals(this.getDescription(), that.getDescription()) && + Objects.equals(this.getStatus(), that.getStatus()) && + Objects.equals(this.getEndpoint(), that.getEndpoint()) && + Objects.equals(this.accessConfig, that.accessConfig) && + Objects.equals(this.encryption, that.encryption) && + Objects.equals(this.iconUrl, that.iconUrl) && + Objects.equals(this.flowTypeOverrides, that.flowTypeOverrides) && + Objects.equals(this.getRule(), that.getRule()); + } + + @Override + public int hashCode() { + + return Objects.hash(getId(), getType(), getName(), getDescription(), getStatus(), getEndpoint(), + accessConfig, encryption, iconUrl, flowTypeOverrides, getRule()); + } + + @Override + public String toString() { + + StringBuilder sb = new StringBuilder(); + sb.append("class InFlowExtensionActionResponse {\n"); + sb.append(" id: ").append(toIndentedString(getId())).append("\n"); + sb.append(" type: ").append(toIndentedString(getType())).append("\n"); + sb.append(" name: ").append(toIndentedString(getName())).append("\n"); + sb.append(" description: ").append(toIndentedString(getDescription())).append("\n"); + sb.append(" status: ").append(toIndentedString(getStatus())).append("\n"); + sb.append(" endpoint: ").append(toIndentedString(getEndpoint())).append("\n"); + sb.append(" accessConfig: ").append(toIndentedString(accessConfig)).append("\n"); + sb.append(" encryption: ").append(toIndentedString(encryption)).append("\n"); + sb.append(" iconUrl: ").append(toIndentedString(iconUrl)).append("\n"); + sb.append(" flowTypeOverrides: ").append(toIndentedString(flowTypeOverrides)).append("\n"); + sb.append(" rule: ").append(toIndentedString(getRule())).append("\n"); + sb.append("}"); + return sb.toString(); + } + + 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.action.management/org.wso2.carbon.identity.api.server.action.management.v1/src/extend/java/org/wso2/carbon/identity/api/server/action/management/v1/InFlowExtensionActionUpdateModel.java b/components/org.wso2.carbon.identity.api.server.action.management/org.wso2.carbon.identity.api.server.action.management.v1/src/extend/java/org/wso2/carbon/identity/api/server/action/management/v1/InFlowExtensionActionUpdateModel.java new file mode 100644 index 0000000000..02714c5475 --- /dev/null +++ b/components/org.wso2.carbon.identity.api.server.action.management/org.wso2.carbon.identity.api.server.action.management.v1/src/extend/java/org/wso2/carbon/identity/api/server/action/management/v1/InFlowExtensionActionUpdateModel.java @@ -0,0 +1,178 @@ +/* + * Copyright (c) 2025, 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.action.management.v1; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.annotations.ApiModelProperty; + +import java.util.Map; +import java.util.Objects; + +import javax.validation.Valid; + +/** + * In-Flow Extension Action Update Model. + * Extends the base ActionUpdateModel with an access configuration. + */ +public class InFlowExtensionActionUpdateModel extends ActionUpdateModel { + + private AccessConfigModel accessConfig; + private EncryptionModel encryption; + private String iconUrl; + private Map flowTypeOverrides; + + public InFlowExtensionActionUpdateModel() { + // Default constructor required for Jackson + } + + public InFlowExtensionActionUpdateModel(ActionUpdateModel actionUpdateModel) { + + setName(actionUpdateModel.getName()); + setDescription(actionUpdateModel.getDescription()); + setEndpoint(actionUpdateModel.getEndpoint()); + setRule(actionUpdateModel.getRule()); + } + + public InFlowExtensionActionUpdateModel accessConfig(AccessConfigModel accessConfig) { + + this.accessConfig = accessConfig; + return this; + } + + @ApiModelProperty() + @JsonProperty("accessConfig") + @Valid + public AccessConfigModel getAccessConfig() { + + return accessConfig; + } + + public void setAccessConfig(AccessConfigModel accessConfig) { + + this.accessConfig = accessConfig; + } + + public InFlowExtensionActionUpdateModel encryption(EncryptionModel encryption) { + + this.encryption = encryption; + return this; + } + + @ApiModelProperty() + @JsonProperty("encryption") + @Valid + public EncryptionModel getEncryption() { + + return encryption; + } + + public void setEncryption(EncryptionModel encryption) { + + this.encryption = encryption; + } + + public InFlowExtensionActionUpdateModel iconUrl(String iconUrl) { + + this.iconUrl = iconUrl; + return this; + } + + @ApiModelProperty() + @JsonProperty("iconUrl") + public String getIconUrl() { + + return iconUrl; + } + + public void setIconUrl(String iconUrl) { + + this.iconUrl = iconUrl; + } + + public InFlowExtensionActionUpdateModel flowTypeOverrides(Map flowTypeOverrides) { + + this.flowTypeOverrides = flowTypeOverrides; + return this; + } + + @ApiModelProperty() + @JsonProperty("flowTypeOverrides") + @Valid + public Map getFlowTypeOverrides() { + + return flowTypeOverrides; + } + + public void setFlowTypeOverrides(Map flowTypeOverrides) { + + this.flowTypeOverrides = flowTypeOverrides; + } + + @Override + public boolean equals(java.lang.Object o) { + + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + InFlowExtensionActionUpdateModel that = (InFlowExtensionActionUpdateModel) o; + return Objects.equals(this.getName(), that.getName()) && + Objects.equals(this.getDescription(), that.getDescription()) && + Objects.equals(this.getEndpoint(), that.getEndpoint()) && + Objects.equals(this.accessConfig, that.accessConfig) && + Objects.equals(this.encryption, that.encryption) && + Objects.equals(this.iconUrl, that.iconUrl) && + Objects.equals(this.flowTypeOverrides, that.flowTypeOverrides) && + Objects.equals(this.getRule(), that.getRule()); + } + + @Override + public int hashCode() { + + return Objects.hash(getName(), getDescription(), getEndpoint(), accessConfig, encryption, iconUrl, + flowTypeOverrides, getRule()); + } + + @Override + public String toString() { + + StringBuilder sb = new StringBuilder(); + sb.append("class InFlowExtensionActionUpdateModel {\n"); + sb.append(" name: ").append(toIndentedString(getName())).append("\n"); + sb.append(" description: ").append(toIndentedString(getDescription())).append("\n"); + sb.append(" endpoint: ").append(toIndentedString(getEndpoint())).append("\n"); + sb.append(" accessConfig: ").append(toIndentedString(accessConfig)).append("\n"); + sb.append(" encryption: ").append(toIndentedString(encryption)).append("\n"); + sb.append(" iconUrl: ").append(toIndentedString(iconUrl)).append("\n"); + sb.append(" flowTypeOverrides: ").append(toIndentedString(flowTypeOverrides)).append("\n"); + sb.append(" rule: ").append(toIndentedString(getRule())).append("\n"); + sb.append("}"); + return sb.toString(); + } + + 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.action.management/org.wso2.carbon.identity.api.server.action.management.v1/src/extend/java/org/wso2/carbon/identity/api/server/action/management/v1/InFlowExtensionBasicResponse.java b/components/org.wso2.carbon.identity.api.server.action.management/org.wso2.carbon.identity.api.server.action.management.v1/src/extend/java/org/wso2/carbon/identity/api/server/action/management/v1/InFlowExtensionBasicResponse.java new file mode 100644 index 0000000000..d690559a64 --- /dev/null +++ b/components/org.wso2.carbon.identity.api.server.action.management/org.wso2.carbon.identity.api.server.action.management.v1/src/extend/java/org/wso2/carbon/identity/api/server/action/management/v1/InFlowExtensionBasicResponse.java @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2025, 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.action.management.v1; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.annotations.ApiModelProperty; + +import java.util.Objects; + +/** + * In-Flow Extension Action Basic Response. + * Extends the base ActionBasicResponse with an optional icon URL. + */ +public class InFlowExtensionBasicResponse extends ActionBasicResponse { + + private String iconUrl; + + public InFlowExtensionBasicResponse(ActionBasicResponse basicResponse) { + + setId(basicResponse.getId()); + setType(basicResponse.getType()); + setName(basicResponse.getName()); + setDescription(basicResponse.getDescription()); + setStatus(basicResponse.getStatus()); + setVersion(basicResponse.getVersion()); + setCreatedAt(basicResponse.getCreatedAt()); + setUpdatedAt(basicResponse.getUpdatedAt()); + setLinks(basicResponse.getLinks()); + } + + public InFlowExtensionBasicResponse iconUrl(String iconUrl) { + + this.iconUrl = iconUrl; + return this; + } + + @ApiModelProperty() + @JsonProperty("iconUrl") + public String getIconUrl() { + + return iconUrl; + } + + public void setIconUrl(String iconUrl) { + + this.iconUrl = iconUrl; + } + + @Override + public boolean equals(java.lang.Object o) { + + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + InFlowExtensionBasicResponse that = (InFlowExtensionBasicResponse) o; + return Objects.equals(this.getId(), that.getId()) && + Objects.equals(this.getType(), that.getType()) && + Objects.equals(this.getName(), that.getName()) && + Objects.equals(this.getDescription(), that.getDescription()) && + Objects.equals(this.getStatus(), that.getStatus()) && + Objects.equals(this.iconUrl, that.iconUrl) && + Objects.equals(this.getLinks(), that.getLinks()); + } + + @Override + public int hashCode() { + + return Objects.hash(getId(), getType(), getName(), getDescription(), getStatus(), iconUrl, getLinks()); + } + + @Override + public String toString() { + + StringBuilder sb = new StringBuilder(); + sb.append("class InFlowExtensionBasicResponse {\n"); + sb.append(" id: ").append(toIndentedString(getId())).append("\n"); + sb.append(" type: ").append(toIndentedString(getType())).append("\n"); + sb.append(" name: ").append(toIndentedString(getName())).append("\n"); + sb.append(" description: ").append(toIndentedString(getDescription())).append("\n"); + sb.append(" status: ").append(toIndentedString(getStatus())).append("\n"); + sb.append(" iconUrl: ").append(toIndentedString(iconUrl)).append("\n"); + sb.append(" links: ").append(toIndentedString(getLinks())).append("\n"); + sb.append("}"); + return sb.toString(); + } + + 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.action.management/org.wso2.carbon.identity.api.server.action.management.v1/src/gen/java/org/wso2/carbon/identity/api/server/action/management/v1/ActionNameCheckRequest.java b/components/org.wso2.carbon.identity.api.server.action.management/org.wso2.carbon.identity.api.server.action.management.v1/src/gen/java/org/wso2/carbon/identity/api/server/action/management/v1/ActionNameCheckRequest.java new file mode 100644 index 0000000000..a15276823f --- /dev/null +++ b/components/org.wso2.carbon.identity.api.server.action.management/org.wso2.carbon.identity.api.server.action.management.v1/src/gen/java/org/wso2/carbon/identity/api/server/action/management/v1/ActionNameCheckRequest.java @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2025, 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.action.management.v1; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.annotations.ApiModelProperty; +import javax.validation.constraints.*; + +import java.util.Objects; +import javax.validation.Valid; + +public class ActionNameCheckRequest { + + private String name; + private String excludeId; + + /** + **/ + public ActionNameCheckRequest name(String name) { + + this.name = name; + return this; + } + + @ApiModelProperty(example = "Access Token Pre Issue", required = true, value = "") + @JsonProperty("name") + @Valid + @NotNull(message = "Property name cannot be null.") + @Size(min=1,max=255) + public String getName() { + return name; + } + public void setName(String name) { + this.name = name; + } + + /** + **/ + public ActionNameCheckRequest excludeId(String excludeId) { + + this.excludeId = excludeId; + return this; + } + + @ApiModelProperty(value = "Action ID to exclude from the uniqueness check (used during update).") + @JsonProperty("excludeId") + @Valid + public String getExcludeId() { + return excludeId; + } + public void setExcludeId(String excludeId) { + this.excludeId = excludeId; + } + + @Override + public boolean equals(java.lang.Object o) { + + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + ActionNameCheckRequest actionNameCheckRequest = (ActionNameCheckRequest) o; + return Objects.equals(this.name, actionNameCheckRequest.name) && + Objects.equals(this.excludeId, actionNameCheckRequest.excludeId); + } + + @Override + public int hashCode() { + return Objects.hash(name, excludeId); + } + + @Override + public String toString() { + + StringBuilder sb = new StringBuilder(); + sb.append("class ActionNameCheckRequest {\n"); + sb.append(" name: ").append(toIndentedString(name)).append("\n"); + sb.append(" excludeId: ").append(toIndentedString(excludeId)).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.action.management/org.wso2.carbon.identity.api.server.action.management.v1/src/gen/java/org/wso2/carbon/identity/api/server/action/management/v1/ActionNameCheckResponse.java b/components/org.wso2.carbon.identity.api.server.action.management/org.wso2.carbon.identity.api.server.action.management.v1/src/gen/java/org/wso2/carbon/identity/api/server/action/management/v1/ActionNameCheckResponse.java new file mode 100644 index 0000000000..5dc358caf6 --- /dev/null +++ b/components/org.wso2.carbon.identity.api.server.action.management/org.wso2.carbon.identity.api.server.action.management.v1/src/gen/java/org/wso2/carbon/identity/api/server/action/management/v1/ActionNameCheckResponse.java @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2025, 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.action.management.v1; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.annotations.ApiModelProperty; + +import java.util.Objects; +import javax.validation.Valid; + +public class ActionNameCheckResponse { + + private Boolean available; + + /** + **/ + public ActionNameCheckResponse available(Boolean available) { + + this.available = available; + return this; + } + + @ApiModelProperty(example = "true", value = "") + @JsonProperty("available") + @Valid + public Boolean getAvailable() { + return available; + } + public void setAvailable(Boolean available) { + this.available = available; + } + + @Override + public boolean equals(java.lang.Object o) { + + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + ActionNameCheckResponse actionNameCheckResponse = (ActionNameCheckResponse) o; + return Objects.equals(this.available, actionNameCheckResponse.available); + } + + @Override + public int hashCode() { + return Objects.hash(available); + } + + @Override + public String toString() { + + StringBuilder sb = new StringBuilder(); + sb.append("class ActionNameCheckResponse {\n"); + sb.append(" available: ").append(toIndentedString(available)).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.action.management/org.wso2.carbon.identity.api.server.action.management.v1/src/gen/java/org/wso2/carbon/identity/api/server/action/management/v1/ActionType.java b/components/org.wso2.carbon.identity.api.server.action.management/org.wso2.carbon.identity.api.server.action.management.v1/src/gen/java/org/wso2/carbon/identity/api/server/action/management/v1/ActionType.java index 90d695c200..c5dbe73cd7 100644 --- a/components/org.wso2.carbon.identity.api.server.action.management/org.wso2.carbon.identity.api.server.action.management.v1/src/gen/java/org/wso2/carbon/identity/api/server/action/management/v1/ActionType.java +++ b/components/org.wso2.carbon.identity.api.server.action.management/org.wso2.carbon.identity.api.server.action.management.v1/src/gen/java/org/wso2/carbon/identity/api/server/action/management/v1/ActionType.java @@ -18,8 +18,12 @@ package org.wso2.carbon.identity.api.server.action.management.v1; +import io.swagger.annotations.ApiModel; import javax.validation.constraints.*; +/** + * Action types supported. As of now, only 'PRE_REGISTRATION' is not implemented. + **/ import javax.xml.bind.annotation.XmlType; import javax.xml.bind.annotation.XmlEnum; import javax.xml.bind.annotation.XmlEnumValue; @@ -28,7 +32,7 @@ @XmlEnum(String.class) public enum ActionType { - @XmlEnumValue("PRE_ISSUE_ACCESS_TOKEN") PRE_ISSUE_ACCESS_TOKEN(String.valueOf("PRE_ISSUE_ACCESS_TOKEN")), @XmlEnumValue("PRE_UPDATE_PASSWORD") PRE_UPDATE_PASSWORD(String.valueOf("PRE_UPDATE_PASSWORD")), @XmlEnumValue("PRE_UPDATE_PROFILE") PRE_UPDATE_PROFILE(String.valueOf("PRE_UPDATE_PROFILE")), @XmlEnumValue("PRE_REGISTRATION") PRE_REGISTRATION(String.valueOf("PRE_REGISTRATION")), @XmlEnumValue("PRE_ISSUE_ID_TOKEN") PRE_ISSUE_ID_TOKEN(String.valueOf("PRE_ISSUE_ID_TOKEN")); + @XmlEnumValue("PRE_ISSUE_ACCESS_TOKEN") PRE_ISSUE_ACCESS_TOKEN(String.valueOf("PRE_ISSUE_ACCESS_TOKEN")), @XmlEnumValue("PRE_UPDATE_PASSWORD") PRE_UPDATE_PASSWORD(String.valueOf("PRE_UPDATE_PASSWORD")), @XmlEnumValue("PRE_UPDATE_PROFILE") PRE_UPDATE_PROFILE(String.valueOf("PRE_UPDATE_PROFILE")), @XmlEnumValue("PRE_REGISTRATION") PRE_REGISTRATION(String.valueOf("PRE_REGISTRATION")), @XmlEnumValue("PRE_ISSUE_ID_TOKEN") PRE_ISSUE_ID_TOKEN(String.valueOf("PRE_ISSUE_ID_TOKEN")), @XmlEnumValue("FLOW_EXTENSIONS") FLOW_EXTENSIONS(String.valueOf("FLOW_EXTENSIONS")); private String value; diff --git a/components/org.wso2.carbon.identity.api.server.action.management/org.wso2.carbon.identity.api.server.action.management.v1/src/gen/java/org/wso2/carbon/identity/api/server/action/management/v1/ActionsApi.java b/components/org.wso2.carbon.identity.api.server.action.management/org.wso2.carbon.identity.api.server.action.management.v1/src/gen/java/org/wso2/carbon/identity/api/server/action/management/v1/ActionsApi.java index f8950db9ca..1c7a934973 100644 --- a/components/org.wso2.carbon.identity.api.server.action.management/org.wso2.carbon.identity.api.server.action.management.v1/src/gen/java/org/wso2/carbon/identity/api/server/action/management/v1/ActionsApi.java +++ b/components/org.wso2.carbon.identity.api.server.action.management/org.wso2.carbon.identity.api.server.action.management.v1/src/gen/java/org/wso2/carbon/identity/api/server/action/management/v1/ActionsApi.java @@ -24,16 +24,22 @@ import java.util.List; import org.wso2.carbon.identity.api.server.action.management.v1.ActionBasicResponse; +import org.wso2.carbon.identity.api.server.action.management.v1.ActionModel; +import org.wso2.carbon.identity.api.server.action.management.v1.ActionNameCheckRequest; +import org.wso2.carbon.identity.api.server.action.management.v1.ActionNameCheckResponse; import org.wso2.carbon.identity.api.server.action.management.v1.ActionResponse; import org.wso2.carbon.identity.api.server.action.management.v1.ActionTypesResponseItem; +import org.wso2.carbon.identity.api.server.action.management.v1.ActionUpdateModel; import org.wso2.carbon.identity.api.server.action.management.v1.Error; import org.wso2.carbon.identity.api.server.action.management.v1.ActionsApiService; +import org.wso2.carbon.identity.api.server.action.management.v1.factories.ActionsApiServiceFactory; import javax.validation.Valid; import javax.ws.rs.*; import javax.ws.rs.core.Response; import io.swagger.annotations.*; -import org.wso2.carbon.identity.api.server.action.management.v1.factories.ActionsApiServiceFactory; + +import javax.validation.constraints.*; @Path("/actions") @Api(description = "The actions API") @@ -67,11 +73,35 @@ public ActionsApi() { @ApiResponse(code = 500, message = "Server Error", response = Error.class), @ApiResponse(code = 501, message = "Not Implemented", response = Error.class) }) - public Response activateAction(@ApiParam(value = "Name of the Action Type.",required=true, allowableValues="preIssueAccessToken, preUpdatePassword, preUpdateProfile, preRegistration, preIssueIdToken") @PathParam("actionType") String actionType, @ApiParam(value = "Unique identifier of the action.",required=true) @PathParam("actionId") String actionId) { + public Response activateAction(@ApiParam(value = "Name of the Action Type.",required=true, allowableValues="preIssueAccessToken, preUpdatePassword, preUpdateProfile, preRegistration, preIssueIdToken, inFlowExtension") @PathParam("actionType") String actionType, @ApiParam(value = "Unique identifier of the action.",required=true) @PathParam("actionId") String actionId) { return delegate.activateAction(actionType, actionId ); } + @Valid + @POST + @Path("/{actionType}/check-name") + @Consumes({ "application/json" }) + @Produces({ "application/json" }) + @ApiOperation(value = "Check Action Name Availability", notes = "This API checks whether the given action name is available for the specified action type. Scope (Permission) required: ``internal_action_mgt_view`` ", response = ActionNameCheckResponse.class, authorizations = { + @Authorization(value = "BasicAuth"), + @Authorization(value = "OAuth2", scopes = { + + }) + }, tags={ "Actions", }) + @ApiResponses(value = { + @ApiResponse(code = 200, message = "OK", response = ActionNameCheckResponse.class), + @ApiResponse(code = 400, message = "Bad Request", response = Error.class), + @ApiResponse(code = 401, message = "Unauthorized", response = Void.class), + @ApiResponse(code = 403, message = "Forbidden", response = Void.class), + @ApiResponse(code = 500, message = "Server Error", response = Error.class), + @ApiResponse(code = 501, message = "Not Implemented", response = Error.class) + }) + public Response checkActionName(@ApiParam(value = "Name of the Action Type.",required=true, allowableValues="preIssueAccessToken, preUpdatePassword, preUpdateProfile, preRegistration, preIssueIdToken, inFlowExtension") @PathParam("actionType") String actionType, @ApiParam(value = "This represents the action name to check." ,required=true) @Valid ActionNameCheckRequest actionNameCheckRequest) { + + return delegate.checkActionName(actionType, actionNameCheckRequest ); + } + @Valid @POST @Path("/{actionType}") @@ -91,7 +121,7 @@ public Response activateAction(@ApiParam(value = "Name of the Action Type.",requ @ApiResponse(code = 500, message = "Server Error", response = Error.class), @ApiResponse(code = 501, message = "Not Implemented", response = Error.class) }) - public Response createAction(@ApiParam(value = "Name of the Action Type.",required=true, allowableValues="preIssueAccessToken, preUpdatePassword, preUpdateProfile, preRegistration, preIssueIdToken") @PathParam("actionType") String actionType, @ApiParam(value = "This represents the information of the action to be created." ,required=true) @Valid String body) { + public Response createAction(@ApiParam(value = "Name of the Action Type.",required=true, allowableValues="preIssueAccessToken, preUpdatePassword, preUpdateProfile, preRegistration, preIssueIdToken, inFlowExtension") @PathParam("actionType") String actionType, @ApiParam(value = "This represents the information of the action to be created." ,required=true) @Valid String body) { return delegate.createAction(actionType, body ); } @@ -116,7 +146,7 @@ public Response createAction(@ApiParam(value = "Name of the Action Type.",requir @ApiResponse(code = 500, message = "Server Error", response = Error.class), @ApiResponse(code = 501, message = "Not Implemented", response = Error.class) }) - public Response deactivateAction(@ApiParam(value = "Name of the Action Type.",required=true, allowableValues="preIssueAccessToken, preUpdatePassword, preUpdateProfile, preRegistration, preIssueIdToken") @PathParam("actionType") String actionType, @ApiParam(value = "Unique identifier of the action.",required=true) @PathParam("actionId") String actionId) { + public Response deactivateAction(@ApiParam(value = "Name of the Action Type.",required=true, allowableValues="preIssueAccessToken, preUpdatePassword, preUpdateProfile, preRegistration, preIssueIdToken, inFlowExtension") @PathParam("actionType") String actionType, @ApiParam(value = "Unique identifier of the action.",required=true) @PathParam("actionId") String actionId) { return delegate.deactivateAction(actionType, actionId ); } @@ -140,7 +170,7 @@ public Response deactivateAction(@ApiParam(value = "Name of the Action Type.",re @ApiResponse(code = 500, message = "Server Error", response = Error.class), @ApiResponse(code = 501, message = "Not Implemented", response = Error.class) }) - public Response deleteAction(@ApiParam(value = "Name of the Action Type.",required=true, allowableValues="preIssueAccessToken, preUpdatePassword, preUpdateProfile, preRegistration, preIssueIdToken") @PathParam("actionType") String actionType, @ApiParam(value = "Unique identifier of the action.",required=true) @PathParam("actionId") String actionId) { + public Response deleteAction(@ApiParam(value = "Name of the Action Type.",required=true, allowableValues="preIssueAccessToken, preUpdatePassword, preUpdateProfile, preRegistration, preIssueIdToken, inFlowExtension") @PathParam("actionType") String actionType, @ApiParam(value = "Unique identifier of the action.",required=true) @PathParam("actionId") String actionId) { return delegate.deleteAction(actionType, actionId ); } @@ -165,7 +195,7 @@ public Response deleteAction(@ApiParam(value = "Name of the Action Type.",requir @ApiResponse(code = 500, message = "Server Error", response = Error.class), @ApiResponse(code = 501, message = "Not Implemented", response = Error.class) }) - public Response getActionByActionId(@ApiParam(value = "Name of the Action Type.",required=true, allowableValues="preIssueAccessToken, preUpdatePassword, preUpdateProfile, preRegistration, preIssueIdToken") @PathParam("actionType") String actionType, @ApiParam(value = "Unique identifier of the action.",required=true) @PathParam("actionId") String actionId) { + public Response getActionByActionId(@ApiParam(value = "Name of the Action Type.",required=true, allowableValues="preIssueAccessToken, preUpdatePassword, preUpdateProfile, preRegistration, preIssueIdToken, inFlowExtension") @PathParam("actionType") String actionType, @ApiParam(value = "Unique identifier of the action.",required=true) @PathParam("actionId") String actionId) { return delegate.getActionByActionId(actionType, actionId ); } @@ -212,7 +242,7 @@ public Response getActionTypes() { @ApiResponse(code = 500, message = "Server Error", response = Error.class), @ApiResponse(code = 501, message = "Not Implemented", response = Error.class) }) - public Response getActionsByActionType(@ApiParam(value = "Name of the Action Type.",required=true, allowableValues="preIssueAccessToken, preUpdatePassword, preUpdateProfile, preRegistration, preIssueIdToken") @PathParam("actionType") String actionType) { + public Response getActionsByActionType(@ApiParam(value = "Name of the Action Type.",required=true, allowableValues="preIssueAccessToken, preUpdatePassword, preUpdateProfile, preRegistration, preIssueIdToken, inFlowExtension") @PathParam("actionType") String actionType) { return delegate.getActionsByActionType(actionType ); } @@ -237,7 +267,7 @@ public Response getActionsByActionType(@ApiParam(value = "Name of the Action Typ @ApiResponse(code = 500, message = "Server Error", response = Error.class), @ApiResponse(code = 501, message = "Not Implemented", response = Error.class) }) - public Response updateAction(@ApiParam(value = "Name of the Action Type.",required=true, allowableValues="preIssueAccessToken, preUpdatePassword, preUpdateProfile, preRegistration, preIssueIdToken") @PathParam("actionType") String actionType, @ApiParam(value = "Unique identifier of the action.",required=true) @PathParam("actionId") String actionId, @ApiParam(value = "This represents the action to be updated." ,required=true) @Valid String body) { + public Response updateAction(@ApiParam(value = "Name of the Action Type.",required=true, allowableValues="preIssueAccessToken, preUpdatePassword, preUpdateProfile, preRegistration, preIssueIdToken, inFlowExtension") @PathParam("actionType") String actionType, @ApiParam(value = "Unique identifier of the action.",required=true) @PathParam("actionId") String actionId, @ApiParam(value = "This represents the action to be updated." ,required=true) @Valid String body) { return delegate.updateAction(actionType, actionId, body ); } diff --git a/components/org.wso2.carbon.identity.api.server.action.management/org.wso2.carbon.identity.api.server.action.management.v1/src/gen/java/org/wso2/carbon/identity/api/server/action/management/v1/ActionsApiService.java b/components/org.wso2.carbon.identity.api.server.action.management/org.wso2.carbon.identity.api.server.action.management.v1/src/gen/java/org/wso2/carbon/identity/api/server/action/management/v1/ActionsApiService.java index 0d977961d2..eae9445d9d 100644 --- a/components/org.wso2.carbon.identity.api.server.action.management/org.wso2.carbon.identity.api.server.action.management.v1/src/gen/java/org/wso2/carbon/identity/api/server/action/management/v1/ActionsApiService.java +++ b/components/org.wso2.carbon.identity.api.server.action.management/org.wso2.carbon.identity.api.server.action.management.v1/src/gen/java/org/wso2/carbon/identity/api/server/action/management/v1/ActionsApiService.java @@ -26,6 +26,8 @@ import java.util.List; import org.wso2.carbon.identity.api.server.action.management.v1.ActionBasicResponse; import org.wso2.carbon.identity.api.server.action.management.v1.ActionModel; +import org.wso2.carbon.identity.api.server.action.management.v1.ActionNameCheckRequest; +import org.wso2.carbon.identity.api.server.action.management.v1.ActionNameCheckResponse; import org.wso2.carbon.identity.api.server.action.management.v1.ActionResponse; import org.wso2.carbon.identity.api.server.action.management.v1.ActionTypesResponseItem; import org.wso2.carbon.identity.api.server.action.management.v1.ActionUpdateModel; @@ -37,6 +39,8 @@ public interface ActionsApiService { public Response activateAction(String actionType, String actionId); + public Response checkActionName(String actionType, ActionNameCheckRequest actionNameCheckRequest); + public Response createAction(String actionType, String body); public Response deactivateAction(String actionType, String actionId); diff --git a/components/org.wso2.carbon.identity.api.server.action.management/org.wso2.carbon.identity.api.server.action.management.v1/src/gen/java/org/wso2/carbon/identity/api/server/action/management/v1/factories/ActionsApiServiceFactory.java b/components/org.wso2.carbon.identity.api.server.action.management/org.wso2.carbon.identity.api.server.action.management.v1/src/gen/java/org/wso2/carbon/identity/api/server/action/management/v1/factories/ActionsApiServiceFactory.java index 7635c3e7ac..96546eac73 100644 --- a/components/org.wso2.carbon.identity.api.server.action.management/org.wso2.carbon.identity.api.server.action.management.v1/src/gen/java/org/wso2/carbon/identity/api/server/action/management/v1/factories/ActionsApiServiceFactory.java +++ b/components/org.wso2.carbon.identity.api.server.action.management/org.wso2.carbon.identity.api.server.action.management.v1/src/gen/java/org/wso2/carbon/identity/api/server/action/management/v1/factories/ActionsApiServiceFactory.java @@ -21,18 +21,10 @@ import org.wso2.carbon.identity.api.server.action.management.v1.ActionsApiService; import org.wso2.carbon.identity.api.server.action.management.v1.impl.ActionsApiServiceImpl; -/** - * Factory class for Actions API Service. - */ public class ActionsApiServiceFactory { private static final ActionsApiService SERVICE = new ActionsApiServiceImpl(); - /** - * Get Actions API Service. - * - * @return ActionsApiService. - */ public static ActionsApiService getActionsApi() { return SERVICE; diff --git a/components/org.wso2.carbon.identity.api.server.action.management/org.wso2.carbon.identity.api.server.action.management.v1/src/main/java/org/wso2/carbon/identity/api/server/action/management/v1/core/ServerActionManagementService.java b/components/org.wso2.carbon.identity.api.server.action.management/org.wso2.carbon.identity.api.server.action.management.v1/src/main/java/org/wso2/carbon/identity/api/server/action/management/v1/core/ServerActionManagementService.java index 8ef77d4685..140bf8a139 100644 --- a/components/org.wso2.carbon.identity.api.server.action.management/org.wso2.carbon.identity.api.server.action.management.v1/src/main/java/org/wso2/carbon/identity/api/server/action/management/v1/core/ServerActionManagementService.java +++ b/components/org.wso2.carbon.identity.api.server.action.management/org.wso2.carbon.identity.api.server.action.management.v1/src/main/java/org/wso2/carbon/identity/api/server/action/management/v1/core/ServerActionManagementService.java @@ -27,6 +27,7 @@ import org.wso2.carbon.identity.action.management.api.service.ActionManagementService; import org.wso2.carbon.identity.api.server.action.management.v1.ActionBasicResponse; import org.wso2.carbon.identity.api.server.action.management.v1.ActionModel; +import org.wso2.carbon.identity.api.server.action.management.v1.ActionNameCheckResponse; import org.wso2.carbon.identity.api.server.action.management.v1.ActionResponse; import org.wso2.carbon.identity.api.server.action.management.v1.ActionType; import org.wso2.carbon.identity.api.server.action.management.v1.ActionTypesResponseItem; @@ -147,7 +148,8 @@ public void deleteAction(String actionType, String actionId) { public ActionBasicResponse activateAction(String actionType, String actionId) { try { - validateActionType(actionType); + Action.ActionTypes validatedActionType = validateActionType(actionType); + validateStatusToggleAllowed(validatedActionType); return buildActionBasicResponse(actionManagementService.activateAction(actionType, actionId, CarbonContext.getThreadLocalCarbonContext().getTenantDomain())); } catch (ActionMgtException e) { @@ -158,7 +160,8 @@ public ActionBasicResponse activateAction(String actionType, String actionId) { public ActionBasicResponse deactivateAction(String actionType, String actionId) { try { - validateActionType(actionType); + Action.ActionTypes validatedActionType = validateActionType(actionType); + validateStatusToggleAllowed(validatedActionType); return buildActionBasicResponse(actionManagementService.deactivateAction(actionType, actionId, CarbonContext.getThreadLocalCarbonContext().getTenantDomain())); } catch (ActionMgtException e) { @@ -166,6 +169,38 @@ public ActionBasicResponse deactivateAction(String actionType, String actionId) } } + public ActionNameCheckResponse checkActionName(String actionType, String name, String excludeId) { + + try { + validateActionType(actionType); + String tenantDomain = CarbonContext.getThreadLocalCarbonContext().getTenantDomain(); + boolean available; +// if (StringUtils.isNotBlank(excludeId)) { +// available = actionManagementService.isActionNameAvailable( +// actionType, name, excludeId, tenantDomain); +// } else { +// available = actionManagementService.isActionNameAvailable(actionType, name, tenantDomain); +// } + return new ActionNameCheckResponse().available(true); + } catch (ActionMgtException e) { + throw ActionMgtEndpointUtil.handleActionMgtException(e); + } + } + + /** + * Validate that status toggle (activate/deactivate) is allowed for the given action type. + * EXTENSION category actions are always active and do not support status toggle. + * + * @param actionType The action type. + */ + private void validateStatusToggleAllowed(Action.ActionTypes actionType) { + + if (Action.ActionTypes.Category.IN_FLOW_EXTENSION.equals(actionType.getCategory())) { + throw ActionMgtEndpointUtil.handleException(Response.Status.BAD_REQUEST, + ERROR_INVALID_ACTION_TYPE); + } + } + public List getActionTypes() { if (LOG.isDebugEnabled()) { @@ -176,6 +211,8 @@ public List getActionTypes() { .getThreadLocalCarbonContext().getTenantDomain()); List actionTypesResponseItems = new ArrayList<>(); + + // Process PRE_POST category action types for (Action.ActionTypes actionType : Action.ActionTypes.filterByCategory( Action.ActionTypes.Category.PRE_POST)) { if (NOT_IMPLEMENTED_ACTION_TYPES.contains(actionType.getPathParam()) || (isOrganization() && @@ -190,6 +227,38 @@ public List getActionTypes() { .count(actionsCountPerType.getOrDefault(actionType.getActionType(), 0)) .self(ActionMgtEndpointUtil.buildURIForActionType(actionType.getActionType()))); } + + // Process IN_FLOW category action types + for (Action.ActionTypes actionType : Action.ActionTypes.filterByCategory( + Action.ActionTypes.Category.IN_FLOW)) { + if (NOT_IMPLEMENTED_ACTION_TYPES.contains(actionType.getPathParam()) || (isOrganization() && + NOT_ALLOWED_ACTION_TYPES_IN_ORG_LEVEL.contains(actionType.getPathParam()))) { + continue; + } + + actionTypesResponseItems.add(new ActionTypesResponseItem() + .type(ActionType.valueOf(actionType.getActionType())) + .displayName(actionType.getDisplayName()) + .description(actionType.getDescription()) + .count(actionsCountPerType.getOrDefault(actionType.getActionType(), 0)) + .self(ActionMgtEndpointUtil.buildURIForActionType(actionType.getActionType()))); + } + + // Process IN_FLOW_EXTENSION category action types + for (Action.ActionTypes actionType : Action.ActionTypes.filterByCategory( + Action.ActionTypes.Category.IN_FLOW_EXTENSION)) { + if (NOT_IMPLEMENTED_ACTION_TYPES.contains(actionType.getPathParam()) || (isOrganization() && + NOT_ALLOWED_ACTION_TYPES_IN_ORG_LEVEL.contains(actionType.getPathParam()))) { + continue; + } + + actionTypesResponseItems.add(new ActionTypesResponseItem() + .type(ActionType.valueOf(actionType.getActionType())) + .displayName(actionType.getDisplayName()) + .description(actionType.getDescription()) + .count(actionsCountPerType.getOrDefault(actionType.getActionType(), 0)) + .self(ActionMgtEndpointUtil.buildURIForActionType(actionType.getActionType()))); + } return actionTypesResponseItems; } catch (ActionMgtException e) { @@ -273,11 +342,34 @@ private Action.ActionTypes validateActionType(String actionType) throws ActionMg private Action.ActionTypes getActionTypeFromPath(String actionType) { - return Arrays.stream(Action.ActionTypes.filterByCategory(Action.ActionTypes.Category.PRE_POST)) + // Check in PRE_POST category + Action.ActionTypes result = Arrays.stream(Action.ActionTypes.filterByCategory( + Action.ActionTypes.Category.PRE_POST)) .filter(actionTypeObj -> actionTypeObj.getPathParam().equals(actionType)) .findFirst() - .orElseThrow(() -> ActionMgtEndpointUtil.handleException(Response.Status.BAD_REQUEST, - ERROR_INVALID_ACTION_TYPE)); + .orElse(null); + + // If not found, check in IN_FLOW category + if (result == null) { + result = Arrays.stream(Action.ActionTypes.filterByCategory(Action.ActionTypes.Category.IN_FLOW)) + .filter(actionTypeObj -> actionTypeObj.getPathParam().equals(actionType)) + .findFirst() + .orElse(null); + } + + // If not found, check in IN_FLOW_EXTENSION category + if (result == null) { + result = Arrays.stream(Action.ActionTypes.filterByCategory(Action.ActionTypes.Category.IN_FLOW_EXTENSION)) + .filter(actionTypeObj -> actionTypeObj.getPathParam().equals(actionType)) + .findFirst() + .orElse(null); + } + + if (result == null) { + throw ActionMgtEndpointUtil.handleException(Response.Status.BAD_REQUEST, ERROR_INVALID_ACTION_TYPE); + } + + return result; } private boolean isOrganization() throws ActionMgtException { diff --git a/components/org.wso2.carbon.identity.api.server.action.management/org.wso2.carbon.identity.api.server.action.management.v1/src/main/java/org/wso2/carbon/identity/api/server/action/management/v1/impl/ActionsApiServiceImpl.java b/components/org.wso2.carbon.identity.api.server.action.management/org.wso2.carbon.identity.api.server.action.management.v1/src/main/java/org/wso2/carbon/identity/api/server/action/management/v1/impl/ActionsApiServiceImpl.java index c297424128..cb304b1315 100644 --- a/components/org.wso2.carbon.identity.api.server.action.management/org.wso2.carbon.identity.api.server.action.management.v1/src/main/java/org/wso2/carbon/identity/api/server/action/management/v1/impl/ActionsApiServiceImpl.java +++ b/components/org.wso2.carbon.identity.api.server.action.management/org.wso2.carbon.identity.api.server.action.management.v1/src/main/java/org/wso2/carbon/identity/api/server/action/management/v1/impl/ActionsApiServiceImpl.java @@ -18,6 +18,7 @@ package org.wso2.carbon.identity.api.server.action.management.v1.impl; +import org.wso2.carbon.identity.api.server.action.management.v1.ActionNameCheckRequest; import org.wso2.carbon.identity.api.server.action.management.v1.ActionResponse; import org.wso2.carbon.identity.api.server.action.management.v1.ActionsApiService; import org.wso2.carbon.identity.api.server.action.management.v1.constants.ActionMgtEndpointConstants; @@ -53,6 +54,13 @@ public Response activateAction(String actionType, String actionId) { return Response.ok().entity(serverActionManagementService.activateAction(actionType, actionId)).build(); } + @Override + public Response checkActionName(String actionType, ActionNameCheckRequest actionNameCheckRequest) { + + return Response.ok().entity(serverActionManagementService.checkActionName(actionType, + actionNameCheckRequest.getName(), actionNameCheckRequest.getExcludeId())).build(); + } + @Override public Response createAction(String actionType, String body) { diff --git a/components/org.wso2.carbon.identity.api.server.action.management/org.wso2.carbon.identity.api.server.action.management.v1/src/main/java/org/wso2/carbon/identity/api/server/action/management/v1/mapper/ActionMapperFactory.java b/components/org.wso2.carbon.identity.api.server.action.management/org.wso2.carbon.identity.api.server.action.management.v1/src/main/java/org/wso2/carbon/identity/api/server/action/management/v1/mapper/ActionMapperFactory.java index 68f96dcf5b..39d3ca81fe 100644 --- a/components/org.wso2.carbon.identity.api.server.action.management/org.wso2.carbon.identity.api.server.action.management.v1/src/main/java/org/wso2/carbon/identity/api/server/action/management/v1/mapper/ActionMapperFactory.java +++ b/components/org.wso2.carbon.identity.api.server.action.management/org.wso2.carbon.identity.api.server.action.management.v1/src/main/java/org/wso2/carbon/identity/api/server/action/management/v1/mapper/ActionMapperFactory.java @@ -48,6 +48,9 @@ public static ActionMapper getActionMapper(Action.ActionTypes actionType) throws case PRE_ISSUE_ID_TOKEN: actionMapper = new PreIssueIDTokenActionMapper(); break; + case FLOW_EXTENSIONS: + actionMapper = new InFlowExtensionActionMapper(); + break; default: break; } diff --git a/components/org.wso2.carbon.identity.api.server.action.management/org.wso2.carbon.identity.api.server.action.management.v1/src/main/java/org/wso2/carbon/identity/api/server/action/management/v1/mapper/InFlowExtensionActionMapper.java b/components/org.wso2.carbon.identity.api.server.action.management/org.wso2.carbon.identity.api.server.action.management.v1/src/main/java/org/wso2/carbon/identity/api/server/action/management/v1/mapper/InFlowExtensionActionMapper.java new file mode 100644 index 0000000000..30389cdc6f --- /dev/null +++ b/components/org.wso2.carbon.identity.api.server.action.management/org.wso2.carbon.identity.api.server.action.management.v1/src/main/java/org/wso2/carbon/identity/api/server/action/management/v1/mapper/InFlowExtensionActionMapper.java @@ -0,0 +1,283 @@ +/* + * Copyright (c) 2025, 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.action.management.v1.mapper; + +import org.wso2.carbon.identity.action.management.api.exception.ActionMgtException; +import org.wso2.carbon.identity.action.management.api.model.Action; +import org.wso2.carbon.identity.api.server.action.management.v1.AccessConfigModel; +import org.wso2.carbon.identity.api.server.action.management.v1.ActionBasicResponse; +import org.wso2.carbon.identity.api.server.action.management.v1.ActionModel; +import org.wso2.carbon.identity.api.server.action.management.v1.ActionResponse; +import org.wso2.carbon.identity.api.server.action.management.v1.ActionUpdateModel; +import org.wso2.carbon.identity.api.server.action.management.v1.EncryptionModel; +import org.wso2.carbon.identity.api.server.action.management.v1.InFlowExtensionActionModel; +import org.wso2.carbon.identity.api.server.action.management.v1.InFlowExtensionActionResponse; +import org.wso2.carbon.identity.api.server.action.management.v1.InFlowExtensionActionUpdateModel; +import org.wso2.carbon.identity.api.server.action.management.v1.InFlowExtensionBasicResponse; +import org.wso2.carbon.identity.api.server.action.management.v1.util.ActionMapperUtil; +import org.wso2.carbon.identity.certificate.management.model.Certificate; +import org.wso2.carbon.identity.flow.extensions.model.AccessConfig; +import org.wso2.carbon.identity.flow.extensions.model.ContextPath; +import org.wso2.carbon.identity.flow.extensions.model.Encryption; +import org.wso2.carbon.identity.flow.extensions.model.InFlowExtensionAction; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * Mapper for In-Flow Extension Action. + */ +public class InFlowExtensionActionMapper implements ActionMapper { + + @Override + public Action.ActionTypes getSupportedActionType() { + + return Action.ActionTypes.FLOW_EXTENSIONS; + } + + @Override + public Action toAction(ActionModel actionModel) throws ActionMgtException { + + if (!(actionModel instanceof InFlowExtensionActionModel)) { + // Fall back to basic action creation if no access config is provided. + return ActionMapperUtil.buildActionRequest(getSupportedActionType(), actionModel); + } + + InFlowExtensionActionModel extModel = (InFlowExtensionActionModel) actionModel; + Action basicAction = ActionMapperUtil.buildActionRequest(getSupportedActionType(), actionModel); + AccessConfig accessConfig = toAccessConfig(extModel.getAccessConfig()); + Encryption encryption = toEncryption(extModel.getEncryption()); + + return new InFlowExtensionAction.RequestBuilder(basicAction) + .accessConfig(accessConfig) + .encryption(encryption) + .iconUrl(extModel.getIconUrl()) + .build(); + } + + @Override + public Action toAction(ActionUpdateModel actionUpdateModel) throws ActionMgtException { + + if (!(actionUpdateModel instanceof InFlowExtensionActionUpdateModel)) { + return ActionMapperUtil.buildUpdatingActionRequest(getSupportedActionType(), actionUpdateModel); + } + + InFlowExtensionActionUpdateModel extUpdateModel = (InFlowExtensionActionUpdateModel) actionUpdateModel; + Action basicUpdatingAction = ActionMapperUtil.buildUpdatingActionRequest(getSupportedActionType(), + actionUpdateModel); + AccessConfig accessConfig = toAccessConfig(extUpdateModel.getAccessConfig()); + Encryption encryption = toEncryption(extUpdateModel.getEncryption()); + + Map flowTypeOverrides = null; + if (extUpdateModel.getFlowTypeOverrides() != null) { + flowTypeOverrides = new HashMap<>(); + for (Map.Entry entry : extUpdateModel.getFlowTypeOverrides().entrySet()) { + flowTypeOverrides.put(entry.getKey(), toAccessConfig(entry.getValue())); + } + } + + return new InFlowExtensionAction.RequestBuilder(basicUpdatingAction) + .accessConfig(accessConfig) + .encryption(encryption) + .iconUrl(extUpdateModel.getIconUrl()) + .flowTypeOverrides(flowTypeOverrides) + .build(); + } + + @Override + public ActionBasicResponse toActionBasicResponse(Action action) throws ActionMgtException { + + ActionBasicResponse basicResponse = ActionMapperUtil.buildActionBasicResponse(action); + + if (!(action instanceof InFlowExtensionAction)) { + return basicResponse; + } + + InFlowExtensionAction extAction = (InFlowExtensionAction) action; + if (extAction.getIconUrl() != null) { + return new InFlowExtensionBasicResponse(basicResponse) + .iconUrl(extAction.getIconUrl()); + } + return basicResponse; + } + + @Override + public ActionResponse toActionResponse(Action action) throws ActionMgtException { + + ActionResponse actionResponse = ActionMapperUtil.buildActionResponse(action); + + if (!(action instanceof InFlowExtensionAction)) { + return actionResponse; + } + + InFlowExtensionAction extAction = (InFlowExtensionAction) action; + AccessConfigModel configModel = toAccessConfigModel(extAction.getAccessConfig()); + EncryptionModel encryptionModel = toEncryptionModel(extAction.getEncryption()); + + InFlowExtensionActionResponse response = new InFlowExtensionActionResponse(actionResponse) + .accessConfig(configModel); + if (encryptionModel != null) { + response.encryption(encryptionModel); + } + if (extAction.getIconUrl() != null) { + response.iconUrl(extAction.getIconUrl()); + } + if (extAction.getFlowTypeOverrides() != null && !extAction.getFlowTypeOverrides().isEmpty()) { + Map overridesModel = new HashMap<>(); + for (Map.Entry entry : extAction.getFlowTypeOverrides().entrySet()) { + overridesModel.put(entry.getKey(), toAccessConfigModel(entry.getValue())); + } + response.flowTypeOverrides(overridesModel); + } + return response; + } + + @SuppressWarnings("unchecked") + private AccessConfig toAccessConfig(AccessConfigModel configModel) { + + if (configModel == null) { + return null; + } + + // Convert expose: List → List. + // Supports both plain strings (encrypted=false) and objects {path, encrypted}. + List exposePaths = null; + if (configModel.getExpose() != null) { + exposePaths = new ArrayList<>(); + for (Object item : configModel.getExpose()) { + if (item instanceof String) { + exposePaths.add(new ContextPath((String) item, false)); + } else if (item instanceof Map) { + Map exposeMap = (Map) item; + String path = (String) exposeMap.get("path"); + boolean encrypted = toBooleanSafe(exposeMap.get("encrypted")); + if (path != null) { + exposePaths.add(new ContextPath(path, encrypted)); + } + } + } + } + + // Convert modify: List → List. + // Same format as expose: supports both plain strings and objects {path, encrypted}. + List modifyPaths = null; + if (configModel.getModify() != null) { + modifyPaths = new ArrayList<>(); + for (Object item : configModel.getModify()) { + if (item instanceof String) { + modifyPaths.add(new ContextPath((String) item, false)); + } else if (item instanceof Map) { + Map modifyMap = (Map) item; + String path = (String) modifyMap.get("path"); + boolean encrypted = toBooleanSafe(modifyMap.get("encrypted")); + if (path != null) { + modifyPaths.add(new ContextPath(path, encrypted)); + } + } + } + } + + return new AccessConfig(exposePaths, modifyPaths); + } + + private Encryption toEncryption(EncryptionModel encryptionModel) { + + if (encryptionModel == null || encryptionModel.getCertificate() == null) { + return null; + } + + // Empty certificate string signals explicit removal of the existing certificate. + if (encryptionModel.getCertificate().isEmpty()) { + return new Encryption(null); + } + + Certificate certificate = new Certificate.Builder() + .name("external-service-cert") + .certificateContent(encryptionModel.getCertificate()) + .build(); + return new Encryption(certificate); + } + + private AccessConfigModel toAccessConfigModel(AccessConfig accessConfig) { + + if (accessConfig == null) { + return null; + } + + // Convert expose: List → List. + // Always output as {path, encrypted} objects for consistency. + List expose = null; + if (accessConfig.getExpose() != null) { + expose = new ArrayList<>(); + for (ContextPath ep : accessConfig.getExpose()) { + Map exposeMap = new HashMap<>(); + exposeMap.put("path", ep.getPath()); + exposeMap.put("encrypted", ep.isEncrypted()); + expose.add(exposeMap); + } + } + + // Convert modify: List → List. + // Always output as {path, encrypted} objects for consistency. + List modify = null; + if (accessConfig.getModify() != null) { + modify = new ArrayList<>(); + for (ContextPath mp : accessConfig.getModify()) { + Map modifyMap = new HashMap<>(); + modifyMap.put("path", mp.getPath()); + modifyMap.put("encrypted", mp.isEncrypted()); + modify.add(modifyMap); + } + } + + return new AccessConfigModel() + .expose(expose) + .modify(modify); + } + + private EncryptionModel toEncryptionModel(Encryption encryption) { + + if (encryption == null || encryption.getCertificate() == null) { + return null; + } + + return new EncryptionModel() + .certificate(encryption.getCertificate().getCertificateContent()); + } + + /** + * Safely converts a value to boolean, handling both {@link Boolean} and {@link String} types. + * Jackson deserializes JSON {@code true} as {@link Boolean} but JSON {@code "true"} as {@link String}. + * + * @param value The value to convert. + * @return {@code true} if the value is Boolean TRUE or the string "true" (case-insensitive). + */ + private static boolean toBooleanSafe(Object value) { + + if (value instanceof Boolean) { + return (Boolean) value; + } + if (value instanceof String) { + return Boolean.parseBoolean((String) value); + } + return false; + } +} diff --git a/components/org.wso2.carbon.identity.api.server.action.management/org.wso2.carbon.identity.api.server.action.management.v1/src/main/java/org/wso2/carbon/identity/api/server/action/management/v1/util/ActionDeserializer.java b/components/org.wso2.carbon.identity.api.server.action.management/org.wso2.carbon.identity.api.server.action.management.v1/src/main/java/org/wso2/carbon/identity/api/server/action/management/v1/util/ActionDeserializer.java index 5770864ed7..cef8dd7f1c 100644 --- a/components/org.wso2.carbon.identity.api.server.action.management/org.wso2.carbon.identity.api.server.action.management.v1/src/main/java/org/wso2/carbon/identity/api/server/action/management/v1/util/ActionDeserializer.java +++ b/components/org.wso2.carbon.identity.api.server.action.management/org.wso2.carbon.identity.api.server.action.management.v1/src/main/java/org/wso2/carbon/identity/api/server/action/management/v1/util/ActionDeserializer.java @@ -23,6 +23,8 @@ import org.wso2.carbon.identity.action.management.api.model.Action; import org.wso2.carbon.identity.api.server.action.management.v1.ActionModel; import org.wso2.carbon.identity.api.server.action.management.v1.ActionUpdateModel; +import org.wso2.carbon.identity.api.server.action.management.v1.InFlowExtensionActionModel; +import org.wso2.carbon.identity.api.server.action.management.v1.InFlowExtensionActionUpdateModel; import org.wso2.carbon.identity.api.server.action.management.v1.PreUpdatePasswordActionModel; import org.wso2.carbon.identity.api.server.action.management.v1.PreUpdatePasswordActionUpdateModel; import org.wso2.carbon.identity.api.server.action.management.v1.PreUpdateProfileActionModel; @@ -62,6 +64,13 @@ public static ActionModel deserializeActionModel(Action.ActionTypes actionType, // Validate the object validateActionModel(actionModel, ActionModel.class); break; + case FLOW_EXTENSIONS: + InFlowExtensionActionModel inFlowExtensionActionModel = objectMapper.readValue(jsonBody, + InFlowExtensionActionModel.class); + // Validate the object + validateActionModel(inFlowExtensionActionModel, InFlowExtensionActionModel.class); + actionModel = inFlowExtensionActionModel; + break; case PRE_UPDATE_PASSWORD: PreUpdatePasswordActionModel preUpdatePasswordActionModel = objectMapper.readValue(jsonBody, PreUpdatePasswordActionModel.class); @@ -105,6 +114,14 @@ public static ActionUpdateModel deserializeActionUpdateModel(Action.ActionTypes // Validate the object validateActionModel(actionUpdateModel, ActionUpdateModel.class); break; + case FLOW_EXTENSIONS: + InFlowExtensionActionUpdateModel inFlowExtensionActionUpdateModel = + objectMapper.readValue(jsonBody, InFlowExtensionActionUpdateModel.class); + // Validate the object + validateActionModel(inFlowExtensionActionUpdateModel, + InFlowExtensionActionUpdateModel.class); + actionUpdateModel = inFlowExtensionActionUpdateModel; + break; case PRE_UPDATE_PASSWORD: PreUpdatePasswordActionUpdateModel preUpdatePasswordActionUpdateModel = objectMapper.readValue(jsonBody, PreUpdatePasswordActionUpdateModel.class); diff --git a/components/org.wso2.carbon.identity.api.server.action.management/org.wso2.carbon.identity.api.server.action.management.v1/src/main/resources/Actions.yaml b/components/org.wso2.carbon.identity.api.server.action.management/org.wso2.carbon.identity.api.server.action.management.v1/src/main/resources/Actions.yaml index 0692d36ce1..d4145bdd53 100644 --- a/components/org.wso2.carbon.identity.api.server.action.management/org.wso2.carbon.identity.api.server.action.management.v1/src/main/resources/Actions.yaml +++ b/components/org.wso2.carbon.identity.api.server.action.management/org.wso2.carbon.identity.api.server.action.management.v1/src/main/resources/Actions.yaml @@ -56,6 +56,11 @@ paths: description: This action invokes before issuing an ID token. count: 1 self: "/api/server/v1/actions/preIssueIdToken" + - type: FLOW_EXTENSIONS + displayName: In-Flow Extension + description: This action invokes during flow execution. + count: 1 + self: "/api/server/v1/actions/inFlowExtension" '401': description: Unauthorized '403': @@ -92,6 +97,7 @@ paths: - preUpdateProfile - preRegistration - preIssueIdToken + - inFlowExtension requestBody: content: application/json: @@ -229,6 +235,39 @@ paths: - field: flow operator: equals value: userInitiatedProfileUpdate + inFlowExtension: + summary: Sample payload for in-flow extension action + value: + name: Risk Assessment Extension + description: This action invokes during flow execution to assess risk. + endpoint: + uri: https://myextension.com/in-flow-extension + authentication: + properties: + header: x-api-key + value: e12595c1-1435-4bf2-94e8-445135ab505a + type: API_KEY + accessConfig: + expose: + - /user/userId + - path: /user/claims/ + encrypted: true + - path: /user/credentials/password + encrypted: true + - /properties/ + - /input/ + - /flow/tenantDomain + - /flow/applicationId + - /flow/flowType + modify: + - /properties/riskScore + - /properties/riskLevel + - /properties/riskFactors[] + - /user/claims/http://wso2.org/claims/country + - path: /user/claims/http://wso2.org/claims/emailaddress + encrypted: true + encryption: + certificate: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURxRENDQXBDZ0F3SUJBZ0l... description: This represents the information of the action to be created. required: true responses: @@ -373,6 +412,41 @@ paths: - field: flow operator: equals value: userInitiatedProfileUpdate + inFlowExtension: + summary: Sample response for in-flow extension action + value: + id: 24f64d17-9824-4e28-8413-de45728d8e84 + name: Risk Assessment Extension + description: This action invokes during flow execution to assess risk. + status: INACTIVE + version: v1 + createdAt: 2025-08-01T12:00:00Z + updatedAt: 2025-09-01T13:00:00Z + endpoint: + uri: https://myextension.com/in-flow-extension + authentication: + type: API_KEY + accessConfig: + expose: + - /user/userId + - path: /user/claims/ + encrypted: true + - path: /user/credentials/password + encrypted: true + - /properties/ + - /input/ + - /flow/tenantDomain + - /flow/applicationId + - /flow/flowType + modify: + - /properties/riskScore + - /properties/riskLevel + - /properties/riskFactors[] + - /user/claims/http://wso2.org/claims/country + - path: /user/claims/http://wso2.org/claims/emailaddress + encrypted: true + encryption: + certificate: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURxRENDQXBDZ0F3SUJBZ0l... '400': description: Bad Request content: @@ -483,6 +557,42 @@ paths: }, "attributes": ["http://wso2.org/claims/givenname", "http://wso2.org/claims/dob"] }' + - lang: Curl - inFlowExtension + source: | + curl --location 'https://localhost:9443/api/server/v1/actions/inFlowExtension' \ + -H 'Authorization: Basic YWRtaW46YWRtaW4=' \ + -H 'Content-Type: application/json' \ + -d '{ + "name": "Risk Assessment Extension", + "description": "This action invokes during flow execution to assess risk.", + "endpoint": { + "uri": "https://myextension.com/in-flow-extension", + "authentication": { + "properties": { + "header": "x-api-key", + "value": "e12595c1-1435-4bf2-94e8-445135ab505a" + }, + "type": "API_KEY" + } + }, + "accessConfig": { + "expose": [ + "/user/userId", + { "path": "/user/claims/", "encrypted": true }, + "/properties/", + "/input/" + ], + "modify": [ + "/properties/riskScore", + "/properties/riskLevel", + "/properties/riskFactors[]", + "/user/claims/http://wso2.org/claims/country" + ] + }, + "encryption": { + "certificate": "LS0tLS1CRUdJTi..." + } + }' x-codegen-request-body-name: body get: @@ -504,6 +614,7 @@ paths: - preUpdateProfile - preRegistration - preIssueIdToken + - inFlowExtension responses: '200': description: OK @@ -572,6 +683,21 @@ paths: - href: "/api/server/v1/actions/preUpdateProfile/24f64d17-9824-4e28-8413-de45728d8e84" method: GET rel: self + inFlowExtension: + summary: Sample response for in-flow extension action + value: + - id: 24f64d17-9824-4e28-8413-de45728d8e84 + type: FLOW_EXTENSIONS + name: Risk Assessment Extension + description: This action invokes during flow execution to assess risk. + status: ACTIVE + version: v1 + createdAt: 2025-08-01T12:00:00Z + updatedAt: 2025-09-01T13:00:00Z + links: + - href: "/api/server/v1/actions/inFlowExtension/24f64d17-9824-4e28-8413-de45728d8e84" + method: GET + rel: self '400': description: Bad Request content: @@ -606,6 +732,57 @@ paths: curl --location 'https://localhost:9443/api/server/v1/actions/{actionType}' \ -H 'Authorization: Basic YWRtaW46YWRtaW4=' + /actions/{actionType}/check-name: + post: + tags: + - Actions + summary: Check Action Name Availability + description: "This API checks whether the given action name is available (unique) within the specified action type.\n\n + Scope (Permission) required: ``internal_action_mgt_view``\n\n" + operationId: checkActionName + parameters: + - name: actionType + in: path + description: Name of the Action Type. + required: true + schema: + enum: + - preIssueAccessToken + - preUpdatePassword + - preUpdateProfile + - preRegistration + - preIssueIdToken + - inFlowExtension + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/ActionNameCheckRequest' + required: true + responses: + '200': + description: Name availability check result + content: + application/json: + schema: + $ref: '#/components/schemas/ActionNameCheckResponse' + '400': + description: Bad Request + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + '401': + description: Unauthorized + '403': + description: Forbidden + '500': + description: Server Error + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + /actions/{actionType}/{actionId}: get: tags: @@ -626,6 +803,7 @@ paths: - preUpdateProfile - preRegistration - preIssueIdToken + - inFlowExtension - name: actionId in: path description: Unique identifier of the action. @@ -778,6 +956,21 @@ paths: - field: flow operator: equals value: userInitiatedProfileUpdate + inFlowExtension: + summary: Sample response for in-flow extension action + value: + id: 24f64d17-9824-4e28-8413-de45728d8e84 + type: FLOW_EXTENSIONS + name: Risk Assessment Extension + description: This action invokes during flow execution to assess risk. + status: ACTIVE + version: v1 + createdAt: 2025-08-01T12:00:00Z + updatedAt: 2025-09-01T13:00:00Z + endpoint: + uri: https://myextension.com/in-flow-extension + authentication: + type: API_KEY '400': description: Bad Request content: @@ -830,6 +1023,7 @@ paths: - preUpdateProfile - preRegistration - preIssueIdToken + - inFlowExtension - name: actionId in: path description: Unique identifier of the action. @@ -949,6 +1143,29 @@ paths: - field: claim operator: notEquals value: http://wso2.org/claims/postalcode + inFlowExtension: + summary: Sample payload for in-flow extension action update + value: + name: Updated Risk Assessment Extension + description: This action invokes during flow execution to assess risk. + version: v2 + endpoint: + uri: https://myextension.com/external/in-flow-extension + authentication: + properties: + token: 346dfbb5-6a8c-447a-9aaa-88fa2dd95962 + type: BEARER + accessConfig: + expose: + - /user/userId + - path: /user/claims/ + encrypted: true + - /properties/ + modify: + - /properties/riskScore + - /properties/riskLevel + encryption: + certificate: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURxRENDQXBDZ0F3SUJBZ0l... description: This represents the action to be updated. required: true responses: @@ -1076,6 +1293,31 @@ paths: - field: claim operator: notEquals value: http://wso2.org/claims/postalcode + inFlowExtension: + summary: Sample response for in-flow extension action update + value: + id: 24f64d17-9824-4e28-8413-de45728d8e84 + name: Updated Risk Assessment Extension + description: This action invokes during flow execution to assess risk. + status: ACTIVE + version: v1 + createdAt: 2025-08-01T12:00:00Z + updatedAt: 2025-09-01T13:00:00Z + endpoint: + uri: https://myextension.com/external/in-flow-extension + authentication: + type: BEARER + accessConfig: + expose: + - /user/userId + - path: /user/claims/ + encrypted: true + - /properties/ + modify: + - /properties/riskScore + - /properties/riskLevel + encryption: + certificate: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURxRENDQXBDZ0F3SUJBZ0l... '400': description: Bad Request content: @@ -1189,6 +1431,39 @@ paths: }, "attributes": ["http://wso2.org/claims/dob"] }' + - lang: Curl - inFlowExtension + source: | + curl --location --request PATCH 'https://localhost:9443/api/server/v1/actions/inFlowExtension/{actionId}' \ + -H 'Content-Type: application/json' \ + -H 'Accept: application/json' \ + -H 'Authorization: Basic YWRtaW46YWRtaW4=' \ + -d '{ + "name": "Updated Risk Assessment Extension", + "description": "This is the configuration of in-flow extension for risk assessment", + "endpoint": { + "uri": "http://myextensions.com/in-flow-extension", + "authentication": { + "type": "BEARER", + "properties": { + "token": "346dfbb5-6a8c-447a-9aaa-88fa2dd95962" + } + } + }, + "accessConfig": { + "expose": [ + "/user/userId", + { "path": "/user/claims/", "encrypted": true }, + "/properties/" + ], + "modify": [ + "/properties/riskScore", + "/properties/riskLevel" + ] + }, + "encryption": { + "certificate": "LS0tLS1CRUdJTi..." + } + }' x-codegen-request-body-name: body delete: @@ -1210,6 +1485,7 @@ paths: - preUpdateProfile - preRegistration - preIssueIdToken + - inFlowExtension - name: actionId in: path description: Unique identifier of the action. @@ -1518,6 +1794,7 @@ components: - PRE_UPDATE_PROFILE - PRE_REGISTRATION - PRE_ISSUE_ID_TOKEN + - FLOW_EXTENSIONS ActionModel: type: object required: @@ -1952,6 +2229,74 @@ components: type: string example: myapp + AccessConfig: + type: object + description: Access configuration specific to In-Flow Extension actions. Defines what context data is exposed to the extension, what operations the extension is allowed to perform, and which paths have encryption enabled. + properties: + expose: + type: array + description: | + List of expose entries defining which parts of the flow context are exposed to the external service. + Each entry can be a plain string (path prefix, no encryption) or an object with `path` and `encrypted` fields. + When `encrypted: true`, the corresponding values are JWE-encrypted before sending to the external service. + items: + oneOf: + - type: string + description: A plain path prefix (encryption defaults to false). + - $ref: '#/components/schemas/ContextPath' + example: + - /user/userId + - path: /user/claims/ + encrypted: true + - path: /user/credentials/password + encrypted: true + - /properties/ + - /input/ + - /flow/tenantDomain + modify: + type: array + description: | + List of context paths the extension is allowed to modify (REPLACE). + Accepts both plain strings (encryption defaults to false) and objects with path and encrypted fields. + items: + oneOf: + - type: string + description: A plain path (encryption defaults to false). + - $ref: '#/components/schemas/ContextPath' + example: + - /properties/riskScore + - /properties/riskLevel + - path: /user/claims/http://wso2.org/claims/emailaddress + encrypted: true + + ContextPath: + type: object + description: A context path entry with an explicit path and optional encryption flag. + required: + - path + properties: + path: + type: string + description: The JSON path prefix. + example: /user/claims/ + encrypted: + type: boolean + description: Whether values under this path should be JWE-encrypted before sending to the external service. + default: false + example: true + + Encryption: + type: object + description: | + Encryption configuration for In-Flow Extension actions. + Contains the external service's X.509 certificate used for JWE encryption (RSA-OAEP-256 + A256GCM). + This follows the same pattern as `passwordSharing.certificate` in Pre Update Password actions. + properties: + certificate: + type: string + description: The external service's X.509 certificate in Base64-encoded PEM format, used for outbound JWE encryption. + example: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURxRENDQXBDZ0F3SUJBZ0l... + Error: type: object properties: @@ -1967,3 +2312,26 @@ components: traceId: type: string example: e0fbcfeb-3617-43c4-8dd0-7b7d38e13047 + + ActionNameCheckRequest: + type: object + required: + - name + properties: + name: + type: string + minLength: 1 + maxLength: 255 + description: The action name to check for availability. + example: Risk Assessment Extension + excludeId: + type: string + description: Action ID to exclude from the uniqueness check (used during update). + + ActionNameCheckResponse: + type: object + properties: + available: + type: boolean + description: Whether the action name is available (unique) within the action type. + example: true diff --git a/components/org.wso2.carbon.identity.api.server.flow.management/org.wso2.carbon.identity.api.server.flow.management.common/src/main/java/org/wso2/carbon/identity/api/server/flow/management/common/FlowMgtServiceHolder.java b/components/org.wso2.carbon.identity.api.server.flow.management/org.wso2.carbon.identity.api.server.flow.management.common/src/main/java/org/wso2/carbon/identity/api/server/flow/management/common/FlowMgtServiceHolder.java index b2069cb2b3..0ca47b400c 100644 --- a/components/org.wso2.carbon.identity.api.server.flow.management/org.wso2.carbon.identity.api.server.flow.management.common/src/main/java/org/wso2/carbon/identity/api/server/flow/management/common/FlowMgtServiceHolder.java +++ b/components/org.wso2.carbon.identity.api.server.flow.management/org.wso2.carbon.identity.api.server.flow.management.common/src/main/java/org/wso2/carbon/identity/api/server/flow/management/common/FlowMgtServiceHolder.java @@ -19,6 +19,7 @@ package org.wso2.carbon.identity.api.server.flow.management.common; import org.wso2.carbon.context.PrivilegedCarbonContext; +import org.wso2.carbon.identity.action.management.api.service.ActionManagementService; import org.wso2.carbon.identity.flow.mgt.FlowAIService; import org.wso2.carbon.identity.flow.mgt.FlowMgtService; import org.wso2.carbon.identity.governance.IdentityGovernanceService; @@ -67,6 +68,13 @@ private static class WorkflowServiceHolder { .getOSGiService(WorkflowManagementService.class, null); } + private static class ActionManagementServiceHolder { + + private static final ActionManagementService SERVICE = + (ActionManagementService) PrivilegedCarbonContext.getThreadLocalCarbonContext() + .getOSGiService(ActionManagementService.class, null); + } + /** * Get FlowMgtService OSGi service. * @@ -116,4 +124,14 @@ public static WorkflowManagementService getWorkflowManagementService() { return WorkflowServiceHolder.SERVICE; } + + /** + * Get ActionManagementService OSGi service. + * + * @return ActionManagementService + */ + public static ActionManagementService getActionManagementService() { + + return ActionManagementServiceHolder.SERVICE; + } } diff --git a/components/org.wso2.carbon.identity.api.server.flow.management/org.wso2.carbon.identity.api.server.flow.management.v1/pom.xml b/components/org.wso2.carbon.identity.api.server.flow.management/org.wso2.carbon.identity.api.server.flow.management.v1/pom.xml index 504d536803..79629aea98 100644 --- a/components/org.wso2.carbon.identity.api.server.flow.management/org.wso2.carbon.identity.api.server.flow.management.v1/pom.xml +++ b/components/org.wso2.carbon.identity.api.server.flow.management/org.wso2.carbon.identity.api.server.flow.management.v1/pom.xml @@ -99,6 +99,14 @@ org.wso2.carbon.identity.framework org.wso2.carbon.identity.flow.mgt + + org.wso2.carbon.identity.framework + org.wso2.carbon.identity.flow.execution.engine + + + org.wso2.carbon.identity.framework + org.wso2.carbon.identity.flow.extensions + org.testng testng @@ -133,6 +141,12 @@ org.wso2.carbon.identity.server.api org.wso2.carbon.identity.api.server.claim.management.common + + jakarta.xml.bind + jakarta.xml.bind-api + 4.0.4 + compile + diff --git a/components/org.wso2.carbon.identity.api.server.flow.management/org.wso2.carbon.identity.api.server.flow.management.v1/src/gen/java/org/wso2/carbon/identity/api/server/flow/management/v1/AccessConfig.java b/components/org.wso2.carbon.identity.api.server.flow.management/org.wso2.carbon.identity.api.server.flow.management.v1/src/gen/java/org/wso2/carbon/identity/api/server/flow/management/v1/AccessConfig.java new file mode 100644 index 0000000000..56664ccc1b --- /dev/null +++ b/components/org.wso2.carbon.identity.api.server.flow.management/org.wso2.carbon.identity.api.server.flow.management.v1/src/gen/java/org/wso2/carbon/identity/api/server/flow/management/v1/AccessConfig.java @@ -0,0 +1,140 @@ +/* + * Copyright (c) 2025, 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.flow.management.v1; + +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.flow.management.v1.ContextPath; +import javax.validation.constraints.*; + + +import io.swagger.annotations.*; +import java.util.Objects; +import javax.validation.Valid; +import javax.xml.bind.annotation.*; + +public class AccessConfig { + + private List expose = null; + + private List modify = null; + + + /** + **/ + public AccessConfig expose(List expose) { + + this.expose = expose; + return this; + } + + @ApiModelProperty(value = "") + @JsonProperty("expose") + @Valid + public List getExpose() { + return expose; + } + public void setExpose(List expose) { + this.expose = expose; + } + + public AccessConfig addExposeItem(ContextPath exposeItem) { + if (this.expose == null) { + this.expose = new ArrayList(); + } + this.expose.add(exposeItem); + return this; + } + + /** + **/ + public AccessConfig modify(List modify) { + + this.modify = modify; + return this; + } + + @ApiModelProperty(value = "") + @JsonProperty("modify") + @Valid + public List getModify() { + return modify; + } + public void setModify(List modify) { + this.modify = modify; + } + + public AccessConfig addModifyItem(ContextPath modifyItem) { + if (this.modify == null) { + this.modify = new ArrayList(); + } + this.modify.add(modifyItem); + return this; + } + + + + @Override + public boolean equals(java.lang.Object o) { + + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + AccessConfig accessConfig = (AccessConfig) o; + return Objects.equals(this.expose, accessConfig.expose) && + Objects.equals(this.modify, accessConfig.modify); + } + + @Override + public int hashCode() { + return Objects.hash(expose, modify); + } + + @Override + public String toString() { + + StringBuilder sb = new StringBuilder(); + sb.append("class AccessConfig {\n"); + + sb.append(" expose: ").append(toIndentedString(expose)).append("\n"); + sb.append(" modify: ").append(toIndentedString(modify)).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.flow.management/org.wso2.carbon.identity.api.server.flow.management.v1/src/gen/java/org/wso2/carbon/identity/api/server/flow/management/v1/AuthenticationType.java b/components/org.wso2.carbon.identity.api.server.flow.management/org.wso2.carbon.identity.api.server.flow.management.v1/src/gen/java/org/wso2/carbon/identity/api/server/flow/management/v1/AuthenticationType.java new file mode 100644 index 0000000000..9e95c83092 --- /dev/null +++ b/components/org.wso2.carbon.identity.api.server.flow.management/org.wso2.carbon.identity.api.server.flow.management.v1/src/gen/java/org/wso2/carbon/identity/api/server/flow/management/v1/AuthenticationType.java @@ -0,0 +1,167 @@ +/* + * Copyright (c) 2025, 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.flow.management.v1; + +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")), @XmlEnumValue("CLIENT_CREDENTIAL") CLIENT_CREDENTIAL(String.valueOf("CLIENT_CREDENTIAL")); + + + 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 = null; + + + /** + **/ + public AuthenticationType type(TypeEnum type) { + + this.type = type; + return this; + } + + @ApiModelProperty(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(value = "") + @JsonProperty("properties") + @Valid + public Map getProperties() { + return properties; + } + public void setProperties(Map properties) { + this.properties = properties; + } + + + public AuthenticationType putPropertiesItem(String key, Object propertiesItem) { + if (this.properties == null) { + this.properties = new HashMap(); + } + 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.flow.management/org.wso2.carbon.identity.api.server.flow.management.v1/src/gen/java/org/wso2/carbon/identity/api/server/flow/management/v1/AuthenticationTypeResponse.java b/components/org.wso2.carbon.identity.api.server.flow.management/org.wso2.carbon.identity.api.server.flow.management.v1/src/gen/java/org/wso2/carbon/identity/api/server/flow/management/v1/AuthenticationTypeResponse.java new file mode 100644 index 0000000000..a6d8a058d4 --- /dev/null +++ b/components/org.wso2.carbon.identity.api.server.flow.management/org.wso2.carbon.identity.api.server.flow.management.v1/src/gen/java/org/wso2/carbon/identity/api/server/flow/management/v1/AuthenticationTypeResponse.java @@ -0,0 +1,131 @@ +/* + * Copyright (c) 2025, 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.flow.management.v1; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import javax.validation.constraints.*; + + +import io.swagger.annotations.*; +import java.util.Objects; +import javax.validation.Valid; +import javax.xml.bind.annotation.*; + +public class AuthenticationTypeResponse { + + +@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")), @XmlEnumValue("CLIENT_CREDENTIAL") CLIENT_CREDENTIAL(String.valueOf("CLIENT_CREDENTIAL")); + + + 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; + + /** + **/ + public AuthenticationTypeResponse type(TypeEnum type) { + + this.type = type; + return this; + } + + @ApiModelProperty(value = "") + @JsonProperty("type") + @Valid + public TypeEnum getType() { + return type; + } + public void setType(TypeEnum type) { + this.type = type; + } + + + + @Override + public boolean equals(java.lang.Object o) { + + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + AuthenticationTypeResponse authenticationTypeResponse = (AuthenticationTypeResponse) o; + return Objects.equals(this.type, authenticationTypeResponse.type); + } + + @Override + public int hashCode() { + return Objects.hash(type); + } + + @Override + public String toString() { + + StringBuilder sb = new StringBuilder(); + sb.append("class AuthenticationTypeResponse {\n"); + + sb.append(" type: ").append(toIndentedString(type)).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.flow.management/org.wso2.carbon.identity.api.server.flow.management.v1/src/gen/java/org/wso2/carbon/identity/api/server/flow/management/v1/ContextPath.java b/components/org.wso2.carbon.identity.api.server.flow.management/org.wso2.carbon.identity.api.server.flow.management.v1/src/gen/java/org/wso2/carbon/identity/api/server/flow/management/v1/ContextPath.java new file mode 100644 index 0000000000..2c43d2c759 --- /dev/null +++ b/components/org.wso2.carbon.identity.api.server.flow.management/org.wso2.carbon.identity.api.server.flow.management.v1/src/gen/java/org/wso2/carbon/identity/api/server/flow/management/v1/ContextPath.java @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2025, 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.flow.management.v1; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import javax.validation.constraints.*; + + +import io.swagger.annotations.*; +import java.util.Objects; +import javax.validation.Valid; +import javax.xml.bind.annotation.*; + +public class ContextPath { + + private String path; + private Boolean encrypted = false; + + /** + **/ + public ContextPath path(String path) { + + this.path = path; + return this; + } + + @ApiModelProperty(required = true, value = "") + @JsonProperty("path") + @Valid + @NotNull(message = "Property path cannot be null.") + + public String getPath() { + return path; + } + public void setPath(String path) { + this.path = path; + } + + /** + **/ + public ContextPath encrypted(Boolean encrypted) { + + this.encrypted = encrypted; + return this; + } + + @ApiModelProperty(value = "") + @JsonProperty("encrypted") + @Valid + public Boolean getEncrypted() { + return encrypted; + } + public void setEncrypted(Boolean encrypted) { + this.encrypted = encrypted; + } + + + + @Override + public boolean equals(java.lang.Object o) { + + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + ContextPath contextPath = (ContextPath) o; + return Objects.equals(this.path, contextPath.path) && + Objects.equals(this.encrypted, contextPath.encrypted); + } + + @Override + public int hashCode() { + return Objects.hash(path, encrypted); + } + + @Override + public String toString() { + + StringBuilder sb = new StringBuilder(); + sb.append("class ContextPath {\n"); + + sb.append(" path: ").append(toIndentedString(path)).append("\n"); + sb.append(" encrypted: ").append(toIndentedString(encrypted)).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.flow.management/org.wso2.carbon.identity.api.server.flow.management.v1/src/gen/java/org/wso2/carbon/identity/api/server/flow/management/v1/Encryption.java b/components/org.wso2.carbon.identity.api.server.flow.management/org.wso2.carbon.identity.api.server.flow.management.v1/src/gen/java/org/wso2/carbon/identity/api/server/flow/management/v1/Encryption.java new file mode 100644 index 0000000000..b1222fb598 --- /dev/null +++ b/components/org.wso2.carbon.identity.api.server.flow.management/org.wso2.carbon.identity.api.server.flow.management.v1/src/gen/java/org/wso2/carbon/identity/api/server/flow/management/v1/Encryption.java @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2025, 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.flow.management.v1; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import javax.validation.constraints.*; + + +import io.swagger.annotations.*; +import java.util.Objects; +import javax.validation.Valid; +import javax.xml.bind.annotation.*; + +public class Encryption { + + private String certificate; + + /** + **/ + public Encryption certificate(String certificate) { + + this.certificate = certificate; + return this; + } + + @ApiModelProperty(value = "") + @JsonProperty("certificate") + @Valid + public String getCertificate() { + return certificate; + } + public void setCertificate(String certificate) { + this.certificate = certificate; + } + + + + @Override + public boolean equals(java.lang.Object o) { + + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + Encryption encryption = (Encryption) o; + return Objects.equals(this.certificate, encryption.certificate); + } + + @Override + public int hashCode() { + return Objects.hash(certificate); + } + + @Override + public String toString() { + + StringBuilder sb = new StringBuilder(); + sb.append("class Encryption {\n"); + + sb.append(" certificate: ").append(toIndentedString(certificate)).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.flow.management/org.wso2.carbon.identity.api.server.flow.management.v1/src/gen/java/org/wso2/carbon/identity/api/server/flow/management/v1/Endpoint.java b/components/org.wso2.carbon.identity.api.server.flow.management/org.wso2.carbon.identity.api.server.flow.management.v1/src/gen/java/org/wso2/carbon/identity/api/server/flow/management/v1/Endpoint.java new file mode 100644 index 0000000000..ef337c2589 --- /dev/null +++ b/components/org.wso2.carbon.identity.api.server.flow.management/org.wso2.carbon.identity.api.server.flow.management.v1/src/gen/java/org/wso2/carbon/identity/api/server/flow/management/v1/Endpoint.java @@ -0,0 +1,156 @@ +/* + * Copyright (c) 2025, 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.flow.management.v1; + +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.flow.management.v1.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; + private List allowedHeaders = null; + + + /** + **/ + public Endpoint uri(String uri) { + + this.uri = uri; + return this; + } + + @ApiModelProperty(required = true, value = "") + @JsonProperty("uri") + @Valid + @NotNull(message = "Property uri cannot be null.") + @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(required = true, value = "") + @JsonProperty("authentication") + @Valid + @NotNull(message = "Property authentication cannot be null.") + + public AuthenticationType getAuthentication() { + return authentication; + } + public void setAuthentication(AuthenticationType authentication) { + this.authentication = authentication; + } + + /** + **/ + public Endpoint allowedHeaders(List allowedHeaders) { + + this.allowedHeaders = allowedHeaders; + return this; + } + + @ApiModelProperty(value = "") + @JsonProperty("allowedHeaders") + @Valid + public List getAllowedHeaders() { + return allowedHeaders; + } + public void setAllowedHeaders(List allowedHeaders) { + this.allowedHeaders = allowedHeaders; + } + + public Endpoint addAllowedHeadersItem(String allowedHeadersItem) { + if (this.allowedHeaders == null) { + this.allowedHeaders = new ArrayList(); + } + this.allowedHeaders.add(allowedHeadersItem); + return this; + } + + + + @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) && + Objects.equals(this.allowedHeaders, endpoint.allowedHeaders); + } + + @Override + public int hashCode() { + return Objects.hash(uri, authentication, allowedHeaders); + } + + @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(" allowedHeaders: ").append(toIndentedString(allowedHeaders)).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.flow.management/org.wso2.carbon.identity.api.server.flow.management.v1/src/gen/java/org/wso2/carbon/identity/api/server/flow/management/v1/EndpointResponse.java b/components/org.wso2.carbon.identity.api.server.flow.management/org.wso2.carbon.identity.api.server.flow.management.v1/src/gen/java/org/wso2/carbon/identity/api/server/flow/management/v1/EndpointResponse.java new file mode 100644 index 0000000000..0581dfac7b --- /dev/null +++ b/components/org.wso2.carbon.identity.api.server.flow.management/org.wso2.carbon.identity.api.server.flow.management.v1/src/gen/java/org/wso2/carbon/identity/api/server/flow/management/v1/EndpointResponse.java @@ -0,0 +1,152 @@ +/* + * Copyright (c) 2025, 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.flow.management.v1; + +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.flow.management.v1.AuthenticationTypeResponse; +import javax.validation.constraints.*; + + +import io.swagger.annotations.*; +import java.util.Objects; +import javax.validation.Valid; +import javax.xml.bind.annotation.*; + +public class EndpointResponse { + + private String uri; + private AuthenticationTypeResponse authentication; + private List allowedHeaders = null; + + + /** + **/ + public EndpointResponse uri(String uri) { + + this.uri = uri; + return this; + } + + @ApiModelProperty(value = "") + @JsonProperty("uri") + @Valid + public String getUri() { + return uri; + } + public void setUri(String uri) { + this.uri = uri; + } + + /** + **/ + public EndpointResponse authentication(AuthenticationTypeResponse authentication) { + + this.authentication = authentication; + return this; + } + + @ApiModelProperty(value = "") + @JsonProperty("authentication") + @Valid + public AuthenticationTypeResponse getAuthentication() { + return authentication; + } + public void setAuthentication(AuthenticationTypeResponse authentication) { + this.authentication = authentication; + } + + /** + **/ + public EndpointResponse allowedHeaders(List allowedHeaders) { + + this.allowedHeaders = allowedHeaders; + return this; + } + + @ApiModelProperty(value = "") + @JsonProperty("allowedHeaders") + @Valid + public List getAllowedHeaders() { + return allowedHeaders; + } + public void setAllowedHeaders(List allowedHeaders) { + this.allowedHeaders = allowedHeaders; + } + + public EndpointResponse addAllowedHeadersItem(String allowedHeadersItem) { + if (this.allowedHeaders == null) { + this.allowedHeaders = new ArrayList(); + } + this.allowedHeaders.add(allowedHeadersItem); + return this; + } + + + + @Override + public boolean equals(java.lang.Object o) { + + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + EndpointResponse endpointResponse = (EndpointResponse) o; + return Objects.equals(this.uri, endpointResponse.uri) && + Objects.equals(this.authentication, endpointResponse.authentication) && + Objects.equals(this.allowedHeaders, endpointResponse.allowedHeaders); + } + + @Override + public int hashCode() { + return Objects.hash(uri, authentication, allowedHeaders); + } + + @Override + public String toString() { + + StringBuilder sb = new StringBuilder(); + sb.append("class EndpointResponse {\n"); + + sb.append(" uri: ").append(toIndentedString(uri)).append("\n"); + sb.append(" authentication: ").append(toIndentedString(authentication)).append("\n"); + sb.append(" allowedHeaders: ").append(toIndentedString(allowedHeaders)).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.flow.management/org.wso2.carbon.identity.api.server.flow.management.v1/src/gen/java/org/wso2/carbon/identity/api/server/flow/management/v1/EndpointUpdateModel.java b/components/org.wso2.carbon.identity.api.server.flow.management/org.wso2.carbon.identity.api.server.flow.management.v1/src/gen/java/org/wso2/carbon/identity/api/server/flow/management/v1/EndpointUpdateModel.java new file mode 100644 index 0000000000..861ebbaf8e --- /dev/null +++ b/components/org.wso2.carbon.identity.api.server.flow.management/org.wso2.carbon.identity.api.server.flow.management.v1/src/gen/java/org/wso2/carbon/identity/api/server/flow/management/v1/EndpointUpdateModel.java @@ -0,0 +1,152 @@ +/* + * Copyright (c) 2025, 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.flow.management.v1; + +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.flow.management.v1.AuthenticationType; +import javax.validation.constraints.*; + + +import io.swagger.annotations.*; +import java.util.Objects; +import javax.validation.Valid; +import javax.xml.bind.annotation.*; + +public class EndpointUpdateModel { + + private String uri; + private AuthenticationType authentication; + private List allowedHeaders = null; + + + /** + **/ + public EndpointUpdateModel uri(String uri) { + + this.uri = uri; + return this; + } + + @ApiModelProperty(value = "") + @JsonProperty("uri") + @Valid @Pattern(regexp="^https?://.+") + public String getUri() { + return uri; + } + public void setUri(String uri) { + this.uri = uri; + } + + /** + **/ + public EndpointUpdateModel 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; + } + + /** + **/ + public EndpointUpdateModel allowedHeaders(List allowedHeaders) { + + this.allowedHeaders = allowedHeaders; + return this; + } + + @ApiModelProperty(value = "") + @JsonProperty("allowedHeaders") + @Valid + public List getAllowedHeaders() { + return allowedHeaders; + } + public void setAllowedHeaders(List allowedHeaders) { + this.allowedHeaders = allowedHeaders; + } + + public EndpointUpdateModel addAllowedHeadersItem(String allowedHeadersItem) { + if (this.allowedHeaders == null) { + this.allowedHeaders = new ArrayList(); + } + this.allowedHeaders.add(allowedHeadersItem); + return this; + } + + + + @Override + public boolean equals(java.lang.Object o) { + + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + EndpointUpdateModel endpointUpdateModel = (EndpointUpdateModel) o; + return Objects.equals(this.uri, endpointUpdateModel.uri) && + Objects.equals(this.authentication, endpointUpdateModel.authentication) && + Objects.equals(this.allowedHeaders, endpointUpdateModel.allowedHeaders); + } + + @Override + public int hashCode() { + return Objects.hash(uri, authentication, allowedHeaders); + } + + @Override + public String toString() { + + StringBuilder sb = new StringBuilder(); + sb.append("class EndpointUpdateModel {\n"); + + sb.append(" uri: ").append(toIndentedString(uri)).append("\n"); + sb.append(" authentication: ").append(toIndentedString(authentication)).append("\n"); + sb.append(" allowedHeaders: ").append(toIndentedString(allowedHeaders)).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.flow.management/org.wso2.carbon.identity.api.server.flow.management.v1/src/gen/java/org/wso2/carbon/identity/api/server/flow/management/v1/FlowApi.java b/components/org.wso2.carbon.identity.api.server.flow.management/org.wso2.carbon.identity.api.server.flow.management.v1/src/gen/java/org/wso2/carbon/identity/api/server/flow/management/v1/FlowApi.java index 123f426216..f9e973d567 100644 --- a/components/org.wso2.carbon.identity.api.server.flow.management/org.wso2.carbon.identity.api.server.flow.management.v1/src/gen/java/org/wso2/carbon/identity/api/server/flow/management/v1/FlowApi.java +++ b/components/org.wso2.carbon.identity.api.server.flow.management/org.wso2.carbon.identity.api.server.flow.management.v1/src/gen/java/org/wso2/carbon/identity/api/server/flow/management/v1/FlowApi.java @@ -52,6 +52,52 @@ public FlowApi() { this.delegate = FlowApiServiceFactory.getFlowApi(); } + @Valid + @POST + @Path("/in-flow-extensions/check-name") + @Consumes({ "application/json" }) + @Produces({ "application/json" }) + @ApiOperation(value = "Check Extension Name Availability", notes = "Checks whether the given in-flow extension name is available. Scope (Permission) required: ``internal_flow_mgt_view`` ", response = InFlowExtensionNameCheckResponse.class, authorizations = { + @Authorization(value = "BasicAuth"), + @Authorization(value = "OAuth2", scopes = { + + }) + }, tags={ "Flow Composer - Extensions", }) + @ApiResponses(value = { + @ApiResponse(code = 200, message = "Name availability check result", response = InFlowExtensionNameCheckResponse.class), + @ApiResponse(code = 400, message = "Bad Request", response = Error.class), + @ApiResponse(code = 401, message = "Unauthorized", response = Void.class), + @ApiResponse(code = 403, message = "Forbidden", response = Void.class), + @ApiResponse(code = 500, message = "Server Error", response = Void.class) + }) + public Response checkInFlowExtensionName(@ApiParam(value = "" ,required=true) @Valid InFlowExtensionNameCheckRequest inFlowExtensionNameCheckRequest) { + + return delegate.checkInFlowExtensionName(inFlowExtensionNameCheckRequest ); + } + + @Valid + @POST + @Path("/in-flow-extensions") + @Consumes({ "application/json" }) + @Produces({ "application/json" }) + @ApiOperation(value = "Create In-Flow Extension", notes = "Creates an in-flow extension and returns the details along with the unique ID. Scope (Permission) required: ``internal_flow_mgt_update`` ", response = InFlowExtensionResponse.class, authorizations = { + @Authorization(value = "BasicAuth"), + @Authorization(value = "OAuth2", scopes = { + + }) + }, tags={ "Flow Composer - Extensions", }) + @ApiResponses(value = { + @ApiResponse(code = 201, message = "In-Flow Extension Created", response = InFlowExtensionResponse.class), + @ApiResponse(code = 400, message = "Bad Request", response = Error.class), + @ApiResponse(code = 401, message = "Unauthorized", response = Void.class), + @ApiResponse(code = 403, message = "Forbidden", response = Void.class), + @ApiResponse(code = 500, message = "Server Error", response = Error.class) + }) + public Response createInFlowExtension(@ApiParam(value = "" ,required=true) @Valid InFlowExtensionModel inFlowExtensionModel) { + + return delegate.createInFlowExtension(inFlowExtensionModel ); + } + @Valid @DELETE @@ -76,6 +122,29 @@ public Response deleteFlow(@Valid @NotNull(message = "Property cannot be null." return delegate.deleteFlow(flowType); } + @Valid + @DELETE + @Path("/in-flow-extensions/{extensionId}") + + + @ApiOperation(value = "Delete In-Flow Extension", notes = "Deletes an in-flow extension by its ID. Scope (Permission) required: ``internal_flow_mgt_update`` ", response = Void.class, authorizations = { + @Authorization(value = "BasicAuth"), + @Authorization(value = "OAuth2", scopes = { + + }) + }, tags={ "Flow Composer - Extensions", }) + @ApiResponses(value = { + @ApiResponse(code = 204, message = "Extension Deleted", response = Void.class), + @ApiResponse(code = 400, message = "Bad Request", response = Void.class), + @ApiResponse(code = 401, message = "Unauthorized", response = Void.class), + @ApiResponse(code = 403, message = "Forbidden", response = Void.class), + @ApiResponse(code = 500, message = "Server Error", response = Void.class) + }) + public Response deleteInFlowExtension(@ApiParam(value = "Unique identifier of the extension.",required=true) @PathParam("extensionId") String extensionId) { + + return delegate.deleteInFlowExtension(extensionId ); + } + @Valid @POST @Path("/generate") @@ -235,6 +304,73 @@ public Response getFlowMeta(@Valid @NotNull(message = "Property cannot be null. return delegate.getFlowMeta(flowType); } + @Valid + @GET + @Path("/in-flow-extensions/{extensionId}") + + @Produces({ "application/json" }) + @ApiOperation(value = "Retrieve In-Flow Extension by ID", notes = "Retrieves the in-flow extension by its ID. Scope (Permission) required: ``internal_flow_mgt_view`` ", response = InFlowExtensionResponse.class, authorizations = { + @Authorization(value = "BasicAuth"), + @Authorization(value = "OAuth2", scopes = { + + }) + }, tags={ "Flow Composer - Extensions", }) + @ApiResponses(value = { + @ApiResponse(code = 200, message = "OK", response = InFlowExtensionResponse.class), + @ApiResponse(code = 401, message = "Unauthorized", response = Void.class), + @ApiResponse(code = 403, message = "Forbidden", response = Void.class), + @ApiResponse(code = 404, message = "Not Found", response = Void.class), + @ApiResponse(code = 500, message = "Server Error", response = Void.class) + }) + public Response getInFlowExtensionById(@ApiParam(value = "Unique identifier of the extension.",required=true) @PathParam("extensionId") String extensionId) { + + return delegate.getInFlowExtensionById(extensionId ); + } + + @Valid + @GET + @Path("/in-flow-extension/context-tree") + + @Produces({ "application/json" }) + @ApiOperation(value = "Retrieve the controlled In-Flow Extension context tree", notes = "Returns the canonical context tree filtered by the deployment.toml whitelist ([identity.in_flow_extension.context.{flow_type}]) for the given flow type. When `flowType` is omitted the default tree is returned. Used by the Console UI to render the In-Flow Extension access-config editor without offering paths the deployment has switched off, and to drive per-flow-type policy flags such as `redirectionEnabled` and `allowReadOnlyClaimsModification`. ", response = InFlowExtensionContextTreeResponse.class, authorizations = { + @Authorization(value = "BasicAuth"), + @Authorization(value = "OAuth2", scopes = { + + }) + }, tags={ "Flow Composer", }) + @ApiResponses(value = { + @ApiResponse(code = 200, message = "Successfully retrieved the context tree", response = InFlowExtensionContextTreeResponse.class), + @ApiResponse(code = 400, message = "Invalid flow type specified", response = Error.class), + @ApiResponse(code = 401, message = "Unauthorized", response = Error.class), + @ApiResponse(code = 403, message = "Forbidden", response = Error.class) + }) + public Response getInFlowExtensionContextTree( @Valid@ApiParam(value = "Optional flow type. When omitted, the default tree is returned.", allowableValues="REGISTRATION, PASSWORD_RECOVERY, INVITED_USER_REGISTRATION, ASK_PASSWORD") @QueryParam("flowType") String flowType) { + + return delegate.getInFlowExtensionContextTree(flowType ); + } + + @Valid + @GET + @Path("/in-flow-extensions") + + @Produces({ "application/json" }) + @ApiOperation(value = "List In-Flow Extensions", notes = "Returns a list of all configured in-flow extensions. Scope (Permission) required: ``internal_flow_mgt_view`` ", response = InFlowExtensionBasicResponse.class, responseContainer = "List", authorizations = { + @Authorization(value = "BasicAuth"), + @Authorization(value = "OAuth2", scopes = { + + }) + }, tags={ "Flow Composer - Extensions", }) + @ApiResponses(value = { + @ApiResponse(code = 200, message = "OK", response = InFlowExtensionBasicResponse.class, responseContainer = "List"), + @ApiResponse(code = 401, message = "Unauthorized", response = Void.class), + @ApiResponse(code = 403, message = "Forbidden", response = Void.class), + @ApiResponse(code = 500, message = "Server Error", response = Error.class) + }) + public Response getInFlowExtensions() { + + return delegate.getInFlowExtensions(); + } + @Valid @PUT @@ -284,4 +420,28 @@ public Response updateFlowConfig(@ApiParam(value = "", required = true) @Valid F return delegate.updateFlowConfig(flowConfigPatchModel); } + @Valid + @PATCH + @Path("/in-flow-extensions/{extensionId}") + @Consumes({ "application/json" }) + @Produces({ "application/json" }) + @ApiOperation(value = "Update In-Flow Extension", notes = "Updates an existing in-flow extension. Scope (Permission) required: ``internal_flow_mgt_update`` ", response = InFlowExtensionResponse.class, authorizations = { + @Authorization(value = "BasicAuth"), + @Authorization(value = "OAuth2", scopes = { + + }) + }, tags={ "Flow Composer - Extensions" }) + @ApiResponses(value = { + @ApiResponse(code = 200, message = "Extension Updated", response = InFlowExtensionResponse.class), + @ApiResponse(code = 400, message = "Bad Request", response = Void.class), + @ApiResponse(code = 401, message = "Unauthorized", response = Void.class), + @ApiResponse(code = 403, message = "Forbidden", response = Void.class), + @ApiResponse(code = 404, message = "Not Found", response = Void.class), + @ApiResponse(code = 500, message = "Server Error", response = Void.class) + }) + public Response updateInFlowExtension(@ApiParam(value = "Unique identifier of the extension.",required=true) @PathParam("extensionId") String extensionId, @ApiParam(value = "" ,required=true) @Valid InFlowExtensionUpdateModel inFlowExtensionUpdateModel) { + + return delegate.updateInFlowExtension(extensionId, inFlowExtensionUpdateModel ); + } + } diff --git a/components/org.wso2.carbon.identity.api.server.flow.management/org.wso2.carbon.identity.api.server.flow.management.v1/src/gen/java/org/wso2/carbon/identity/api/server/flow/management/v1/FlowApiService.java b/components/org.wso2.carbon.identity.api.server.flow.management/org.wso2.carbon.identity.api.server.flow.management.v1/src/gen/java/org/wso2/carbon/identity/api/server/flow/management/v1/FlowApiService.java index c2426233f3..7445a683ee 100644 --- a/components/org.wso2.carbon.identity.api.server.flow.management/org.wso2.carbon.identity.api.server.flow.management.v1/src/gen/java/org/wso2/carbon/identity/api/server/flow/management/v1/FlowApiService.java +++ b/components/org.wso2.carbon.identity.api.server.flow.management/org.wso2.carbon.identity.api.server.flow.management.v1/src/gen/java/org/wso2/carbon/identity/api/server/flow/management/v1/FlowApiService.java @@ -23,23 +23,37 @@ public interface FlowApiService { - public Response deleteFlow(String flowType); + public Response checkInFlowExtensionName(InFlowExtensionNameCheckRequest inFlowExtensionNameCheckRequest); - public Response generateFlow(FlowGenerateRequest flowGenerateRequest); + public Response createInFlowExtension(InFlowExtensionModel inFlowExtensionModel); - public Response getFlow(String flowType); + public Response deleteFlow(String flowType); - public Response getFlowConfigForFlow(String flowType); + public Response deleteInFlowExtension(String extensionId); - public Response getFlowConfigs(); + public Response generateFlow(FlowGenerateRequest flowGenerateRequest); - public Response getFlowGenerationResult(String operationId); + public Response getFlow(String flowType); - public Response getFlowGenerationStatus(String operationId); + public Response getFlowConfigForFlow(String flowType); - public Response getFlowMeta(String flowType); + public Response getFlowConfigs(); - public Response updateFlow(FlowRequest flowRequest); + public Response getFlowGenerationResult(String operationId); - public Response updateFlowConfig(FlowConfigPatchModel flowConfigPatchModel); + public Response getFlowGenerationStatus(String operationId); + + public Response getFlowMeta(String flowType); + + public Response getInFlowExtensionById(String extensionId); + + public Response getInFlowExtensionContextTree(String flowType); + + public Response getInFlowExtensions(); + + public Response updateFlow(FlowRequest flowRequest); + + public Response updateFlowConfig(FlowConfigPatchModel flowConfigPatchModel); + + public Response updateInFlowExtension(String extensionId, InFlowExtensionUpdateModel inFlowExtensionUpdateModel); } diff --git a/components/org.wso2.carbon.identity.api.server.flow.management/org.wso2.carbon.identity.api.server.flow.management.v1/src/gen/java/org/wso2/carbon/identity/api/server/flow/management/v1/FlowMetaResponse.java b/components/org.wso2.carbon.identity.api.server.flow.management/org.wso2.carbon.identity.api.server.flow.management.v1/src/gen/java/org/wso2/carbon/identity/api/server/flow/management/v1/FlowMetaResponse.java index 080b55e3bd..d0ce3798e3 100644 --- a/components/org.wso2.carbon.identity.api.server.flow.management/org.wso2.carbon.identity.api.server.flow.management.v1/src/gen/java/org/wso2/carbon/identity/api/server/flow/management/v1/FlowMetaResponse.java +++ b/components/org.wso2.carbon.identity.api.server.flow.management/org.wso2.carbon.identity.api.server.flow.management.v1/src/gen/java/org/wso2/carbon/identity/api/server/flow/management/v1/FlowMetaResponse.java @@ -19,23 +19,18 @@ package org.wso2.carbon.identity.api.server.flow.management.v1; 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.flow.management.v1.AttributeMetadata; -import org.wso2.carbon.identity.api.server.flow.management.v1.ExecutorConnections; -import javax.validation.constraints.*; /** * General metadata for a flow type **/ -import io.swagger.annotations.*; import java.util.Objects; import javax.validation.Valid; -import javax.xml.bind.annotation.*; + @ApiModel(description = "General metadata for a flow type") public class FlowMetaResponse { @@ -50,6 +45,8 @@ public class FlowMetaResponse { private List executorConnections = null; + private List inflowExtensionConnections = null; + private Boolean workflowEnabled; /** @@ -212,6 +209,32 @@ public FlowMetaResponse addExecutorConnectionsItem(ExecutorConnections executorC /** **/ + public FlowMetaResponse inflowExtensionConnections(List inflowExtensionConnections) { + + this.inflowExtensionConnections = inflowExtensionConnections; + return this; + } + + @ApiModelProperty(value = "") + @JsonProperty("inflowExtensionConnections") + @Valid + public List getInflowExtensionConnections() { + return inflowExtensionConnections; + } + public void setInflowExtensionConnections(List inflowExtensionConnections) { + this.inflowExtensionConnections = inflowExtensionConnections; + } + + public FlowMetaResponse addInflowExtensionConnectionsItem(InFlowExtensionConnectionInfo item) { + if (this.inflowExtensionConnections == null) { + this.inflowExtensionConnections = new ArrayList(); + } + this.inflowExtensionConnections.add(item); + return this; + } + + /** + **/ public FlowMetaResponse workflowEnabled(Boolean workflowEnabled) { this.workflowEnabled = workflowEnabled; @@ -247,12 +270,13 @@ public boolean equals(java.lang.Object o) { Objects.equals(this.supportedFlowCompletionConfigs, flowMetaResponse.supportedFlowCompletionConfigs) && Objects.equals(this.attributeMetadata, flowMetaResponse.attributeMetadata) && Objects.equals(this.executorConnections, flowMetaResponse.executorConnections) && + Objects.equals(this.inflowExtensionConnections, flowMetaResponse.inflowExtensionConnections) && Objects.equals(this.workflowEnabled, flowMetaResponse.workflowEnabled); } @Override public int hashCode() { - return Objects.hash(flowType, supportedExecutors, connectorConfigs, attributeProfile, supportedFlowCompletionConfigs, attributeMetadata, executorConnections, workflowEnabled); + return Objects.hash(flowType, supportedExecutors, connectorConfigs, attributeProfile, supportedFlowCompletionConfigs, attributeMetadata, executorConnections, inflowExtensionConnections, workflowEnabled); } @Override @@ -268,6 +292,7 @@ public String toString() { sb.append(" supportedFlowCompletionConfigs: ").append(toIndentedString(supportedFlowCompletionConfigs)).append("\n"); sb.append(" attributeMetadata: ").append(toIndentedString(attributeMetadata)).append("\n"); sb.append(" executorConnections: ").append(toIndentedString(executorConnections)).append("\n"); + sb.append(" inflowExtensionConnections: ").append(toIndentedString(inflowExtensionConnections)).append("\n"); sb.append(" workflowEnabled: ").append(toIndentedString(workflowEnabled)).append("\n"); sb.append("}"); return sb.toString(); diff --git a/components/org.wso2.carbon.identity.api.server.flow.management/org.wso2.carbon.identity.api.server.flow.management.v1/src/gen/java/org/wso2/carbon/identity/api/server/flow/management/v1/InFlowExtensionBasicResponse.java b/components/org.wso2.carbon.identity.api.server.flow.management/org.wso2.carbon.identity.api.server.flow.management.v1/src/gen/java/org/wso2/carbon/identity/api/server/flow/management/v1/InFlowExtensionBasicResponse.java new file mode 100644 index 0000000000..2b085b4711 --- /dev/null +++ b/components/org.wso2.carbon.identity.api.server.flow.management/org.wso2.carbon.identity.api.server.flow.management.v1/src/gen/java/org/wso2/carbon/identity/api/server/flow/management/v1/InFlowExtensionBasicResponse.java @@ -0,0 +1,311 @@ +/* + * Copyright (c) 2025, 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.flow.management.v1; + +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.flow.management.v1.Link; +import javax.validation.constraints.*; + + +import io.swagger.annotations.*; +import java.util.Objects; +import javax.validation.Valid; +import javax.xml.bind.annotation.*; + +public class InFlowExtensionBasicResponse { + + private String id; + private String name; + private String description; + private String iconUrl; + +@jakarta.xml.bind.annotation.XmlType(name="StatusEnum") +@XmlEnum(String.class) +public enum StatusEnum { + + @XmlEnumValue("ACTIVE") ACTIVE(String.valueOf("ACTIVE")), @XmlEnumValue("INACTIVE") INACTIVE(String.valueOf("INACTIVE")); + + + private String value; + + StatusEnum(String v) { + value = v; + } + + public String value() { + return value; + } + + @Override + public String toString() { + return String.valueOf(value); + } + + public static StatusEnum fromValue(String value) { + for (StatusEnum b : StatusEnum.values()) { + if (b.value.equals(value)) { + return b; + } + } + throw new IllegalArgumentException("Unexpected value '" + value + "'"); + } +} + + private StatusEnum status; + private String version; + private String createdAt; + private String updatedAt; + private List links = null; + + + /** + **/ + public InFlowExtensionBasicResponse id(String id) { + + this.id = id; + return this; + } + + @ApiModelProperty(value = "") + @JsonProperty("id") + @Valid + public String getId() { + return id; + } + public void setId(String id) { + this.id = id; + } + + /** + **/ + public InFlowExtensionBasicResponse name(String name) { + + this.name = name; + return this; + } + + @ApiModelProperty(value = "") + @JsonProperty("name") + @Valid + public String getName() { + return name; + } + public void setName(String name) { + this.name = name; + } + + /** + **/ + public InFlowExtensionBasicResponse description(String description) { + + this.description = description; + return this; + } + + @ApiModelProperty(value = "") + @JsonProperty("description") + @Valid + public String getDescription() { + return description; + } + public void setDescription(String description) { + this.description = description; + } + + /** + **/ + public InFlowExtensionBasicResponse iconUrl(String iconUrl) { + + this.iconUrl = iconUrl; + return this; + } + + @ApiModelProperty(value = "") + @JsonProperty("iconUrl") + @Valid + public String getIconUrl() { + return iconUrl; + } + public void setIconUrl(String iconUrl) { + this.iconUrl = iconUrl; + } + + /** + **/ + public InFlowExtensionBasicResponse status(StatusEnum status) { + + this.status = status; + return this; + } + + @ApiModelProperty(value = "") + @JsonProperty("status") + @Valid + public StatusEnum getStatus() { + return status; + } + public void setStatus(StatusEnum status) { + this.status = status; + } + + /** + **/ + public InFlowExtensionBasicResponse version(String version) { + + this.version = version; + return this; + } + + @ApiModelProperty(value = "") + @JsonProperty("version") + @Valid + public String getVersion() { + return version; + } + public void setVersion(String version) { + this.version = version; + } + + /** + **/ + public InFlowExtensionBasicResponse createdAt(String createdAt) { + + this.createdAt = createdAt; + return this; + } + + @ApiModelProperty(value = "") + @JsonProperty("createdAt") + @Valid + public String getCreatedAt() { + return createdAt; + } + public void setCreatedAt(String createdAt) { + this.createdAt = createdAt; + } + + /** + **/ + public InFlowExtensionBasicResponse updatedAt(String updatedAt) { + + this.updatedAt = updatedAt; + return this; + } + + @ApiModelProperty(value = "") + @JsonProperty("updatedAt") + @Valid + public String getUpdatedAt() { + return updatedAt; + } + public void setUpdatedAt(String updatedAt) { + this.updatedAt = updatedAt; + } + + /** + **/ + public InFlowExtensionBasicResponse links(List links) { + + this.links = links; + return this; + } + + @ApiModelProperty(value = "") + @JsonProperty("links") + @Valid + public List getLinks() { + return links; + } + public void setLinks(List links) { + this.links = links; + } + + public InFlowExtensionBasicResponse addLinksItem(Link linksItem) { + if (this.links == null) { + this.links = new ArrayList(); + } + this.links.add(linksItem); + return this; + } + + + + @Override + public boolean equals(java.lang.Object o) { + + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + InFlowExtensionBasicResponse inFlowExtensionBasicResponse = (InFlowExtensionBasicResponse) o; + return Objects.equals(this.id, inFlowExtensionBasicResponse.id) && + Objects.equals(this.name, inFlowExtensionBasicResponse.name) && + Objects.equals(this.description, inFlowExtensionBasicResponse.description) && + Objects.equals(this.iconUrl, inFlowExtensionBasicResponse.iconUrl) && + Objects.equals(this.status, inFlowExtensionBasicResponse.status) && + Objects.equals(this.version, inFlowExtensionBasicResponse.version) && + Objects.equals(this.createdAt, inFlowExtensionBasicResponse.createdAt) && + Objects.equals(this.updatedAt, inFlowExtensionBasicResponse.updatedAt) && + Objects.equals(this.links, inFlowExtensionBasicResponse.links); + } + + @Override + public int hashCode() { + return Objects.hash(id, name, description, iconUrl, status, version, createdAt, updatedAt, links); + } + + @Override + public String toString() { + + StringBuilder sb = new StringBuilder(); + sb.append("class InFlowExtensionBasicResponse {\n"); + + sb.append(" id: ").append(toIndentedString(id)).append("\n"); + sb.append(" name: ").append(toIndentedString(name)).append("\n"); + sb.append(" description: ").append(toIndentedString(description)).append("\n"); + sb.append(" iconUrl: ").append(toIndentedString(iconUrl)).append("\n"); + sb.append(" status: ").append(toIndentedString(status)).append("\n"); + sb.append(" version: ").append(toIndentedString(version)).append("\n"); + sb.append(" createdAt: ").append(toIndentedString(createdAt)).append("\n"); + sb.append(" updatedAt: ").append(toIndentedString(updatedAt)).append("\n"); + sb.append(" links: ").append(toIndentedString(links)).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.flow.management/org.wso2.carbon.identity.api.server.flow.management.v1/src/gen/java/org/wso2/carbon/identity/api/server/flow/management/v1/InFlowExtensionConnectionInfo.java b/components/org.wso2.carbon.identity.api.server.flow.management/org.wso2.carbon.identity.api.server.flow.management.v1/src/gen/java/org/wso2/carbon/identity/api/server/flow/management/v1/InFlowExtensionConnectionInfo.java new file mode 100644 index 0000000000..53370c61eb --- /dev/null +++ b/components/org.wso2.carbon.identity.api.server.flow.management/org.wso2.carbon.identity.api.server.flow.management.v1/src/gen/java/org/wso2/carbon/identity/api/server/flow/management/v1/InFlowExtensionConnectionInfo.java @@ -0,0 +1,141 @@ +/* + * Copyright (c) 2025, 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.flow.management.v1; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; + +import java.util.Objects; +import javax.validation.Valid; + +/** + * Represents a single active in-flow extension connection available for use in flow builders. + */ +@ApiModel(description = "In-flow extension connection info for flow metadata") +public class InFlowExtensionConnectionInfo { + + private String actionId; + private String name; + private String iconUrl; + + /** + **/ + public InFlowExtensionConnectionInfo actionId(String actionId) { + + this.actionId = actionId; + return this; + } + + @ApiModelProperty(value = "") + @JsonProperty("actionId") + @Valid + public String getActionId() { + + return actionId; + } + + public void setActionId(String actionId) { + + this.actionId = actionId; + } + + /** + **/ + public InFlowExtensionConnectionInfo name(String name) { + + this.name = name; + return this; + } + + @ApiModelProperty(value = "") + @JsonProperty("name") + @Valid + public String getName() { + + return name; + } + + public void setName(String name) { + + this.name = name; + } + + /** + **/ + public InFlowExtensionConnectionInfo iconUrl(String iconUrl) { + + this.iconUrl = iconUrl; + return this; + } + + @ApiModelProperty(value = "") + @JsonProperty("iconUrl") + @Valid + public String getIconUrl() { + + return iconUrl; + } + + public void setIconUrl(String iconUrl) { + + this.iconUrl = iconUrl; + } + + @Override + public boolean equals(java.lang.Object o) { + + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + InFlowExtensionConnectionInfo that = (InFlowExtensionConnectionInfo) o; + return Objects.equals(this.actionId, that.actionId) && + Objects.equals(this.name, that.name) && + Objects.equals(this.iconUrl, that.iconUrl); + } + + @Override + public int hashCode() { + + return Objects.hash(actionId, name, iconUrl); + } + + @Override + public String toString() { + + StringBuilder sb = new StringBuilder(); + sb.append("class InFlowExtensionConnectionInfo {\n"); + sb.append(" actionId: ").append(toIndentedString(actionId)).append("\n"); + sb.append(" name: ").append(toIndentedString(name)).append("\n"); + sb.append(" iconUrl: ").append(toIndentedString(iconUrl)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + 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.flow.management/org.wso2.carbon.identity.api.server.flow.management.v1/src/gen/java/org/wso2/carbon/identity/api/server/flow/management/v1/InFlowExtensionContextTreeNode.java b/components/org.wso2.carbon.identity.api.server.flow.management/org.wso2.carbon.identity.api.server.flow.management.v1/src/gen/java/org/wso2/carbon/identity/api/server/flow/management/v1/InFlowExtensionContextTreeNode.java new file mode 100644 index 0000000000..12b3dc4a6b --- /dev/null +++ b/components/org.wso2.carbon.identity.api.server.flow.management/org.wso2.carbon.identity.api.server.flow.management.v1/src/gen/java/org/wso2/carbon/identity/api/server/flow/management/v1/InFlowExtensionContextTreeNode.java @@ -0,0 +1,399 @@ +/* + * Copyright (c) 2025, 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.flow.management.v1; + +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 javax.validation.constraints.*; + +/** + * One node in the controlled In-Flow Extension context tree. + **/ + +import io.swagger.annotations.*; +import java.util.Objects; +import javax.validation.Valid; +import javax.xml.bind.annotation.*; +@ApiModel(description = "One node in the controlled In-Flow Extension context tree.") +public class InFlowExtensionContextTreeNode { + + private String key; + private String title; + private String path; + private String dataType; + +@XmlType(name="NodeTypeEnum") +@XmlEnum(String.class) +public enum NodeTypeEnum { + + @XmlEnumValue("OBJECT") OBJECT(String.valueOf("OBJECT")), @XmlEnumValue("LEAF") LEAF(String.valueOf("LEAF")), @XmlEnumValue("MAP") MAP(String.valueOf("MAP")), @XmlEnumValue("COMPLEX_MAP") COMPLEX_MAP(String.valueOf("COMPLEX_MAP")); + + + private String value; + + NodeTypeEnum(String v) { + value = v; + } + + public String value() { + return value; + } + + @Override + public String toString() { + return String.valueOf(value); + } + + public static NodeTypeEnum fromValue(String value) { + for (NodeTypeEnum b : NodeTypeEnum.values()) { + if (b.value.equals(value)) { + return b; + } + } + throw new IllegalArgumentException("Unexpected value '" + value + "'"); + } +} + + private NodeTypeEnum nodeType; + +@XmlType(name="AllowedOperationsEnum") +@XmlEnum(String.class) +public enum AllowedOperationsEnum { + + @XmlEnumValue("EXPOSE") EXPOSE(String.valueOf("EXPOSE")), @XmlEnumValue("MODIFY") MODIFY(String.valueOf("MODIFY")); + + + private String value; + + AllowedOperationsEnum(String v) { + value = v; + } + + public String value() { + return value; + } + + @Override + public String toString() { + return String.valueOf(value); + } + + public static AllowedOperationsEnum fromValue(String value) { + for (AllowedOperationsEnum b : AllowedOperationsEnum.values()) { + if (b.value.equals(value)) { + return b; + } + } + throw new IllegalArgumentException("Unexpected value '" + value + "'"); + } +} + + private List allowedOperations = null; + + private Boolean readOnly; + private Boolean replaceable; + private Boolean dynamicEntryAllowed; + private String dynamicEntryType; + private List children = null; + + + /** + **/ + public InFlowExtensionContextTreeNode key(String key) { + + this.key = key; + return this; + } + + @ApiModelProperty(example = "userId", value = "") + @JsonProperty("key") + @Valid + public String getKey() { + return key; + } + public void setKey(String key) { + this.key = key; + } + + /** + **/ + public InFlowExtensionContextTreeNode title(String title) { + + this.title = title; + return this; + } + + @ApiModelProperty(example = "User ID", value = "") + @JsonProperty("title") + @Valid + public String getTitle() { + return title; + } + public void setTitle(String title) { + this.title = title; + } + + /** + **/ + public InFlowExtensionContextTreeNode path(String path) { + + this.path = path; + return this; + } + + @ApiModelProperty(example = "/user/userId", value = "") + @JsonProperty("path") + @Valid + public String getPath() { + return path; + } + public void setPath(String path) { + this.path = path; + } + + /** + **/ + public InFlowExtensionContextTreeNode dataType(String dataType) { + + this.dataType = dataType; + return this; + } + + @ApiModelProperty(example = "String", value = "") + @JsonProperty("dataType") + @Valid + public String getDataType() { + return dataType; + } + public void setDataType(String dataType) { + this.dataType = dataType; + } + + /** + * Tree node type. + **/ + public InFlowExtensionContextTreeNode nodeType(NodeTypeEnum nodeType) { + + this.nodeType = nodeType; + return this; + } + + @ApiModelProperty(example = "LEAF", value = "Tree node type.") + @JsonProperty("nodeType") + @Valid + public NodeTypeEnum getNodeType() { + return nodeType; + } + public void setNodeType(NodeTypeEnum nodeType) { + this.nodeType = nodeType; + } + + /** + * Operations the admin may configure on this node. + **/ + public InFlowExtensionContextTreeNode allowedOperations(List allowedOperations) { + + this.allowedOperations = allowedOperations; + return this; + } + + @ApiModelProperty(value = "Operations the admin may configure on this node.") + @JsonProperty("allowedOperations") + @Valid + public List getAllowedOperations() { + return allowedOperations; + } + public void setAllowedOperations(List allowedOperations) { + this.allowedOperations = allowedOperations; + } + + public InFlowExtensionContextTreeNode addAllowedOperationsItem(AllowedOperationsEnum allowedOperationsItem) { + if (this.allowedOperations == null) { + this.allowedOperations = new ArrayList(); + } + this.allowedOperations.add(allowedOperationsItem); + return this; + } + + /** + **/ + public InFlowExtensionContextTreeNode readOnly(Boolean readOnly) { + + this.readOnly = readOnly; + return this; + } + + @ApiModelProperty(example = "false", value = "") + @JsonProperty("readOnly") + @Valid + public Boolean getReadOnly() { + return readOnly; + } + public void setReadOnly(Boolean readOnly) { + this.readOnly = readOnly; + } + + /** + **/ + public InFlowExtensionContextTreeNode replaceable(Boolean replaceable) { + + this.replaceable = replaceable; + return this; + } + + @ApiModelProperty(example = "false", value = "") + @JsonProperty("replaceable") + @Valid + public Boolean getReplaceable() { + return replaceable; + } + public void setReplaceable(Boolean replaceable) { + this.replaceable = replaceable; + } + + /** + **/ + public InFlowExtensionContextTreeNode dynamicEntryAllowed(Boolean dynamicEntryAllowed) { + + this.dynamicEntryAllowed = dynamicEntryAllowed; + return this; + } + + @ApiModelProperty(example = "true", value = "") + @JsonProperty("dynamicEntryAllowed") + @Valid + public Boolean getDynamicEntryAllowed() { + return dynamicEntryAllowed; + } + public void setDynamicEntryAllowed(Boolean dynamicEntryAllowed) { + this.dynamicEntryAllowed = dynamicEntryAllowed; + } + + /** + **/ + public InFlowExtensionContextTreeNode dynamicEntryType(String dynamicEntryType) { + + this.dynamicEntryType = dynamicEntryType; + return this; + } + + @ApiModelProperty(example = "String", value = "") + @JsonProperty("dynamicEntryType") + @Valid + public String getDynamicEntryType() { + return dynamicEntryType; + } + public void setDynamicEntryType(String dynamicEntryType) { + this.dynamicEntryType = dynamicEntryType; + } + + /** + **/ + public InFlowExtensionContextTreeNode children(List children) { + + this.children = children; + return this; + } + + @ApiModelProperty(value = "") + @JsonProperty("children") + @Valid + public List getChildren() { + return children; + } + public void setChildren(List children) { + this.children = children; + } + + public InFlowExtensionContextTreeNode addChildrenItem(InFlowExtensionContextTreeNode childrenItem) { + if (this.children == null) { + this.children = new ArrayList(); + } + this.children.add(childrenItem); + return this; + } + + + + @Override + public boolean equals(java.lang.Object o) { + + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + InFlowExtensionContextTreeNode inFlowExtensionContextTreeNode = (InFlowExtensionContextTreeNode) o; + return Objects.equals(this.key, inFlowExtensionContextTreeNode.key) && + Objects.equals(this.title, inFlowExtensionContextTreeNode.title) && + Objects.equals(this.path, inFlowExtensionContextTreeNode.path) && + Objects.equals(this.dataType, inFlowExtensionContextTreeNode.dataType) && + Objects.equals(this.nodeType, inFlowExtensionContextTreeNode.nodeType) && + Objects.equals(this.allowedOperations, inFlowExtensionContextTreeNode.allowedOperations) && + Objects.equals(this.readOnly, inFlowExtensionContextTreeNode.readOnly) && + Objects.equals(this.replaceable, inFlowExtensionContextTreeNode.replaceable) && + Objects.equals(this.dynamicEntryAllowed, inFlowExtensionContextTreeNode.dynamicEntryAllowed) && + Objects.equals(this.dynamicEntryType, inFlowExtensionContextTreeNode.dynamicEntryType) && + Objects.equals(this.children, inFlowExtensionContextTreeNode.children); + } + + @Override + public int hashCode() { + return Objects.hash(key, title, path, dataType, nodeType, allowedOperations, readOnly, replaceable, dynamicEntryAllowed, dynamicEntryType, children); + } + + @Override + public String toString() { + + StringBuilder sb = new StringBuilder(); + sb.append("class InFlowExtensionContextTreeNode {\n"); + + sb.append(" key: ").append(toIndentedString(key)).append("\n"); + sb.append(" title: ").append(toIndentedString(title)).append("\n"); + sb.append(" path: ").append(toIndentedString(path)).append("\n"); + sb.append(" dataType: ").append(toIndentedString(dataType)).append("\n"); + sb.append(" nodeType: ").append(toIndentedString(nodeType)).append("\n"); + sb.append(" allowedOperations: ").append(toIndentedString(allowedOperations)).append("\n"); + sb.append(" readOnly: ").append(toIndentedString(readOnly)).append("\n"); + sb.append(" replaceable: ").append(toIndentedString(replaceable)).append("\n"); + sb.append(" dynamicEntryAllowed: ").append(toIndentedString(dynamicEntryAllowed)).append("\n"); + sb.append(" dynamicEntryType: ").append(toIndentedString(dynamicEntryType)).append("\n"); + sb.append(" children: ").append(toIndentedString(children)).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.flow.management/org.wso2.carbon.identity.api.server.flow.management.v1/src/gen/java/org/wso2/carbon/identity/api/server/flow/management/v1/InFlowExtensionContextTreeResponse.java b/components/org.wso2.carbon.identity.api.server.flow.management/org.wso2.carbon.identity.api.server.flow.management.v1/src/gen/java/org/wso2/carbon/identity/api/server/flow/management/v1/InFlowExtensionContextTreeResponse.java new file mode 100644 index 0000000000..f76cb6db8d --- /dev/null +++ b/components/org.wso2.carbon.identity.api.server.flow.management/org.wso2.carbon.identity.api.server.flow.management.v1/src/gen/java/org/wso2/carbon/identity/api/server/flow/management/v1/InFlowExtensionContextTreeResponse.java @@ -0,0 +1,180 @@ +/* + * Copyright (c) 2025, 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.flow.management.v1; + +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.flow.management.v1.InFlowExtensionContextTreeNode; +import javax.validation.constraints.*; + +/** + * Controlled In-Flow Extension context tree for a given flow type, plus per-flow-type policy flags consumed by the Console UI. + **/ + +import io.swagger.annotations.*; +import java.util.Objects; +import javax.validation.Valid; +import javax.xml.bind.annotation.*; +@ApiModel(description = "Controlled In-Flow Extension context tree for a given flow type, plus per-flow-type policy flags consumed by the Console UI. ") +public class InFlowExtensionContextTreeResponse { + + private String flowType; + private List contextTree = null; + + private Boolean redirectionEnabled; + private Boolean allowReadOnlyClaimsModification; + + /** + * Echoed flow type. `null` when no flowType was supplied (default tree). + **/ + public InFlowExtensionContextTreeResponse flowType(String flowType) { + + this.flowType = flowType; + return this; + } + + @ApiModelProperty(example = "PASSWORD_RECOVERY", value = "Echoed flow type. `null` when no flowType was supplied (default tree).") + @JsonProperty("flowType") + @Valid + public String getFlowType() { + return flowType; + } + public void setFlowType(String flowType) { + this.flowType = flowType; + } + + /** + * Tree of context fields available for the active flow type. Fields disabled at the deployment.toml whitelist level are omitted entirely. + **/ + public InFlowExtensionContextTreeResponse contextTree(List contextTree) { + + this.contextTree = contextTree; + return this; + } + + @ApiModelProperty(value = "Tree of context fields available for the active flow type. Fields disabled at the deployment.toml whitelist level are omitted entirely. ") + @JsonProperty("contextTree") + @Valid + public List getContextTree() { + return contextTree; + } + public void setContextTree(List contextTree) { + this.contextTree = contextTree; + } + + public InFlowExtensionContextTreeResponse addContextTreeItem(InFlowExtensionContextTreeNode contextTreeItem) { + if (this.contextTree == null) { + this.contextTree = new ArrayList(); + } + this.contextTree.add(contextTreeItem); + return this; + } + + /** + * Whether REDIRECT is advertised in `allowedOperations` for this flow type. + **/ + public InFlowExtensionContextTreeResponse redirectionEnabled(Boolean redirectionEnabled) { + + this.redirectionEnabled = redirectionEnabled; + return this; + } + + @ApiModelProperty(example = "true", value = "Whether REDIRECT is advertised in `allowedOperations` for this flow type.") + @JsonProperty("redirectionEnabled") + @Valid + public Boolean getRedirectionEnabled() { + return redirectionEnabled; + } + public void setRedirectionEnabled(Boolean redirectionEnabled) { + this.redirectionEnabled = redirectionEnabled; + } + + /** + * Whether the Console UI may permit MODIFY on read-only claims for this flow type. Hardcoded enumerative mapping in the engine. + **/ + public InFlowExtensionContextTreeResponse allowReadOnlyClaimsModification(Boolean allowReadOnlyClaimsModification) { + + this.allowReadOnlyClaimsModification = allowReadOnlyClaimsModification; + return this; + } + + @ApiModelProperty(example = "true", value = "Whether the Console UI may permit MODIFY on read-only claims for this flow type. Hardcoded enumerative mapping in the engine. ") + @JsonProperty("allowReadOnlyClaimsModification") + @Valid + public Boolean getAllowReadOnlyClaimsModification() { + return allowReadOnlyClaimsModification; + } + public void setAllowReadOnlyClaimsModification(Boolean allowReadOnlyClaimsModification) { + this.allowReadOnlyClaimsModification = allowReadOnlyClaimsModification; + } + + + + @Override + public boolean equals(java.lang.Object o) { + + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + InFlowExtensionContextTreeResponse inFlowExtensionContextTreeResponse = (InFlowExtensionContextTreeResponse) o; + return Objects.equals(this.flowType, inFlowExtensionContextTreeResponse.flowType) && + Objects.equals(this.contextTree, inFlowExtensionContextTreeResponse.contextTree) && + Objects.equals(this.redirectionEnabled, inFlowExtensionContextTreeResponse.redirectionEnabled) && + Objects.equals(this.allowReadOnlyClaimsModification, inFlowExtensionContextTreeResponse.allowReadOnlyClaimsModification); + } + + @Override + public int hashCode() { + return Objects.hash(flowType, contextTree, redirectionEnabled, allowReadOnlyClaimsModification); + } + + @Override + public String toString() { + + StringBuilder sb = new StringBuilder(); + sb.append("class InFlowExtensionContextTreeResponse {\n"); + + sb.append(" flowType: ").append(toIndentedString(flowType)).append("\n"); + sb.append(" contextTree: ").append(toIndentedString(contextTree)).append("\n"); + sb.append(" redirectionEnabled: ").append(toIndentedString(redirectionEnabled)).append("\n"); + sb.append(" allowReadOnlyClaimsModification: ").append(toIndentedString(allowReadOnlyClaimsModification)).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.flow.management/org.wso2.carbon.identity.api.server.flow.management.v1/src/gen/java/org/wso2/carbon/identity/api/server/flow/management/v1/InFlowExtensionModel.java b/components/org.wso2.carbon.identity.api.server.flow.management/org.wso2.carbon.identity.api.server.flow.management.v1/src/gen/java/org/wso2/carbon/identity/api/server/flow/management/v1/InFlowExtensionModel.java new file mode 100644 index 0000000000..1bf742113f --- /dev/null +++ b/components/org.wso2.carbon.identity.api.server.flow.management/org.wso2.carbon.identity.api.server.flow.management.v1/src/gen/java/org/wso2/carbon/identity/api/server/flow/management/v1/InFlowExtensionModel.java @@ -0,0 +1,212 @@ +/* + * Copyright (c) 2025, 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.flow.management.v1; + +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.flow.management.v1.AccessConfig; +import org.wso2.carbon.identity.api.server.flow.management.v1.Encryption; +import org.wso2.carbon.identity.api.server.flow.management.v1.Endpoint; +import javax.validation.constraints.*; + + +import io.swagger.annotations.*; +import java.util.Objects; +import javax.validation.Valid; +import javax.xml.bind.annotation.*; + +public class InFlowExtensionModel { + + private String name; + private String description; + private String iconUrl; + private Endpoint endpoint; + private AccessConfig accessConfig; + private Encryption encryption; + + /** + * Name of the extension. + **/ + public InFlowExtensionModel name(String name) { + + this.name = name; + return this; + } + + @ApiModelProperty(example = "Risk Assessment Extension", required = true, value = "Name of the extension.") + @JsonProperty("name") + @Valid + @NotNull(message = "Property name cannot be null.") + + public String getName() { + return name; + } + public void setName(String name) { + this.name = name; + } + + /** + * Description of the extension. + **/ + public InFlowExtensionModel description(String description) { + + this.description = description; + return this; + } + + @ApiModelProperty(example = "This action invokes during flow execution to assess risk.", value = "Description of the extension.") + @JsonProperty("description") + @Valid + public String getDescription() { + return description; + } + public void setDescription(String description) { + this.description = description; + } + + /** + **/ + public InFlowExtensionModel iconUrl(String iconUrl) { + + this.iconUrl = iconUrl; + return this; + } + + @ApiModelProperty(value = "URL for the extension's icon.") + @JsonProperty("iconUrl") + @Valid + public String getIconUrl() { + return iconUrl; + } + public void setIconUrl(String iconUrl) { + this.iconUrl = iconUrl; + } + + /** + **/ + public InFlowExtensionModel endpoint(Endpoint endpoint) { + + this.endpoint = endpoint; + return this; + } + + @ApiModelProperty(required = true, value = "") + @JsonProperty("endpoint") + @Valid + @NotNull(message = "Property endpoint cannot be null.") + + public Endpoint getEndpoint() { + return endpoint; + } + public void setEndpoint(Endpoint endpoint) { + this.endpoint = endpoint; + } + + /** + **/ + public InFlowExtensionModel accessConfig(AccessConfig accessConfig) { + + this.accessConfig = accessConfig; + return this; + } + + @ApiModelProperty(value = "") + @JsonProperty("accessConfig") + @Valid + public AccessConfig getAccessConfig() { + return accessConfig; + } + public void setAccessConfig(AccessConfig accessConfig) { + this.accessConfig = accessConfig; + } + + /** + **/ + public InFlowExtensionModel encryption(Encryption encryption) { + + this.encryption = encryption; + return this; + } + + @ApiModelProperty(value = "") + @JsonProperty("encryption") + @Valid + public Encryption getEncryption() { + return encryption; + } + public void setEncryption(Encryption encryption) { + this.encryption = encryption; + } + + + + @Override + public boolean equals(java.lang.Object o) { + + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + InFlowExtensionModel inFlowExtensionModel = (InFlowExtensionModel) o; + return Objects.equals(this.name, inFlowExtensionModel.name) && + Objects.equals(this.description, inFlowExtensionModel.description) && + Objects.equals(this.iconUrl, inFlowExtensionModel.iconUrl) && + Objects.equals(this.endpoint, inFlowExtensionModel.endpoint) && + Objects.equals(this.accessConfig, inFlowExtensionModel.accessConfig) && + Objects.equals(this.encryption, inFlowExtensionModel.encryption); + } + + @Override + public int hashCode() { + return Objects.hash(name, description, iconUrl, endpoint, accessConfig, encryption); + } + + @Override + public String toString() { + + StringBuilder sb = new StringBuilder(); + sb.append("class InFlowExtensionModel {\n"); + + sb.append(" name: ").append(toIndentedString(name)).append("\n"); + sb.append(" description: ").append(toIndentedString(description)).append("\n"); + sb.append(" iconUrl: ").append(toIndentedString(iconUrl)).append("\n"); + sb.append(" endpoint: ").append(toIndentedString(endpoint)).append("\n"); + sb.append(" accessConfig: ").append(toIndentedString(accessConfig)).append("\n"); + sb.append(" encryption: ").append(toIndentedString(encryption)).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.flow.management/org.wso2.carbon.identity.api.server.flow.management.v1/src/gen/java/org/wso2/carbon/identity/api/server/flow/management/v1/InFlowExtensionNameCheckRequest.java b/components/org.wso2.carbon.identity.api.server.flow.management/org.wso2.carbon.identity.api.server.flow.management.v1/src/gen/java/org/wso2/carbon/identity/api/server/flow/management/v1/InFlowExtensionNameCheckRequest.java new file mode 100644 index 0000000000..09fdf6785e --- /dev/null +++ b/components/org.wso2.carbon.identity.api.server.flow.management/org.wso2.carbon.identity.api.server.flow.management.v1/src/gen/java/org/wso2/carbon/identity/api/server/flow/management/v1/InFlowExtensionNameCheckRequest.java @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2025, 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.flow.management.v1; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import javax.validation.constraints.*; + + +import io.swagger.annotations.*; +import java.util.Objects; +import javax.validation.Valid; +import javax.xml.bind.annotation.*; + +public class InFlowExtensionNameCheckRequest { + + private String name; + private String excludeId; + + /** + **/ + public InFlowExtensionNameCheckRequest name(String name) { + + this.name = name; + return this; + } + + @ApiModelProperty(required = true, value = "") + @JsonProperty("name") + @Valid + @NotNull(message = "Property name cannot be null.") + + public String getName() { + return name; + } + public void setName(String name) { + this.name = name; + } + + /** + **/ + public InFlowExtensionNameCheckRequest excludeId(String excludeId) { + + this.excludeId = excludeId; + return this; + } + + @ApiModelProperty(value = "") + @JsonProperty("excludeId") + @Valid + public String getExcludeId() { + return excludeId; + } + public void setExcludeId(String excludeId) { + this.excludeId = excludeId; + } + + + + @Override + public boolean equals(java.lang.Object o) { + + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + InFlowExtensionNameCheckRequest inFlowExtensionNameCheckRequest = (InFlowExtensionNameCheckRequest) o; + return Objects.equals(this.name, inFlowExtensionNameCheckRequest.name) && + Objects.equals(this.excludeId, inFlowExtensionNameCheckRequest.excludeId); + } + + @Override + public int hashCode() { + return Objects.hash(name, excludeId); + } + + @Override + public String toString() { + + StringBuilder sb = new StringBuilder(); + sb.append("class InFlowExtensionNameCheckRequest {\n"); + + sb.append(" name: ").append(toIndentedString(name)).append("\n"); + sb.append(" excludeId: ").append(toIndentedString(excludeId)).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.flow.management/org.wso2.carbon.identity.api.server.flow.management.v1/src/gen/java/org/wso2/carbon/identity/api/server/flow/management/v1/InFlowExtensionNameCheckResponse.java b/components/org.wso2.carbon.identity.api.server.flow.management/org.wso2.carbon.identity.api.server.flow.management.v1/src/gen/java/org/wso2/carbon/identity/api/server/flow/management/v1/InFlowExtensionNameCheckResponse.java new file mode 100644 index 0000000000..c24184e43f --- /dev/null +++ b/components/org.wso2.carbon.identity.api.server.flow.management/org.wso2.carbon.identity.api.server.flow.management.v1/src/gen/java/org/wso2/carbon/identity/api/server/flow/management/v1/InFlowExtensionNameCheckResponse.java @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2025, 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.flow.management.v1; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import javax.validation.constraints.*; + + +import io.swagger.annotations.*; +import java.util.Objects; +import javax.validation.Valid; +import javax.xml.bind.annotation.*; + +public class InFlowExtensionNameCheckResponse { + + private Boolean available; + + /** + **/ + public InFlowExtensionNameCheckResponse available(Boolean available) { + + this.available = available; + return this; + } + + @ApiModelProperty(value = "") + @JsonProperty("available") + @Valid + public Boolean getAvailable() { + return available; + } + public void setAvailable(Boolean available) { + this.available = available; + } + + + + @Override + public boolean equals(java.lang.Object o) { + + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + InFlowExtensionNameCheckResponse inFlowExtensionNameCheckResponse = (InFlowExtensionNameCheckResponse) o; + return Objects.equals(this.available, inFlowExtensionNameCheckResponse.available); + } + + @Override + public int hashCode() { + return Objects.hash(available); + } + + @Override + public String toString() { + + StringBuilder sb = new StringBuilder(); + sb.append("class InFlowExtensionNameCheckResponse {\n"); + + sb.append(" available: ").append(toIndentedString(available)).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.flow.management/org.wso2.carbon.identity.api.server.flow.management.v1/src/gen/java/org/wso2/carbon/identity/api/server/flow/management/v1/InFlowExtensionResponse.java b/components/org.wso2.carbon.identity.api.server.flow.management/org.wso2.carbon.identity.api.server.flow.management.v1/src/gen/java/org/wso2/carbon/identity/api/server/flow/management/v1/InFlowExtensionResponse.java new file mode 100644 index 0000000000..02d2cfa0c8 --- /dev/null +++ b/components/org.wso2.carbon.identity.api.server.flow.management/org.wso2.carbon.identity.api.server.flow.management.v1/src/gen/java/org/wso2/carbon/identity/api/server/flow/management/v1/InFlowExtensionResponse.java @@ -0,0 +1,344 @@ +/* + * Copyright (c) 2025, 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.flow.management.v1; + +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.flow.management.v1.AccessConfig; +import org.wso2.carbon.identity.api.server.flow.management.v1.Encryption; +import org.wso2.carbon.identity.api.server.flow.management.v1.EndpointResponse; +import javax.validation.constraints.*; + + +import io.swagger.annotations.*; +import java.util.Objects; +import javax.validation.Valid; +import javax.xml.bind.annotation.*; + +public class InFlowExtensionResponse { + + private String id; + private String name; + private String description; + +@XmlType(name="StatusEnum") +@XmlEnum(String.class) +public enum StatusEnum { + + @XmlEnumValue("ACTIVE") ACTIVE(String.valueOf("ACTIVE")), @XmlEnumValue("INACTIVE") INACTIVE(String.valueOf("INACTIVE")); + + + private String value; + + StatusEnum(String v) { + value = v; + } + + public String value() { + return value; + } + + @Override + public String toString() { + return String.valueOf(value); + } + + public static StatusEnum fromValue(String value) { + for (StatusEnum b : StatusEnum.values()) { + if (b.value.equals(value)) { + return b; + } + } + throw new IllegalArgumentException("Unexpected value '" + value + "'"); + } +} + + private StatusEnum status; + private String version; + private String createdAt; + private String updatedAt; + private String iconUrl; + private EndpointResponse endpoint; + private AccessConfig accessConfig; + private Encryption encryption; + + /** + **/ + public InFlowExtensionResponse id(String id) { + + this.id = id; + return this; + } + + @ApiModelProperty(value = "") + @JsonProperty("id") + @Valid + public String getId() { + return id; + } + public void setId(String id) { + this.id = id; + } + + /** + **/ + public InFlowExtensionResponse name(String name) { + + this.name = name; + return this; + } + + @ApiModelProperty(value = "") + @JsonProperty("name") + @Valid + public String getName() { + return name; + } + public void setName(String name) { + this.name = name; + } + + /** + **/ + public InFlowExtensionResponse description(String description) { + + this.description = description; + return this; + } + + @ApiModelProperty(value = "") + @JsonProperty("description") + @Valid + public String getDescription() { + return description; + } + public void setDescription(String description) { + this.description = description; + } + + /** + **/ + public InFlowExtensionResponse status(StatusEnum status) { + + this.status = status; + return this; + } + + @ApiModelProperty(value = "") + @JsonProperty("status") + @Valid + public StatusEnum getStatus() { + return status; + } + public void setStatus(StatusEnum status) { + this.status = status; + } + + /** + **/ + public InFlowExtensionResponse version(String version) { + + this.version = version; + return this; + } + + @ApiModelProperty(value = "") + @JsonProperty("version") + @Valid + public String getVersion() { + return version; + } + public void setVersion(String version) { + this.version = version; + } + + /** + **/ + public InFlowExtensionResponse createdAt(String createdAt) { + + this.createdAt = createdAt; + return this; + } + + @ApiModelProperty(value = "") + @JsonProperty("createdAt") + @Valid + public String getCreatedAt() { + return createdAt; + } + public void setCreatedAt(String createdAt) { + this.createdAt = createdAt; + } + + /** + **/ + public InFlowExtensionResponse updatedAt(String updatedAt) { + + this.updatedAt = updatedAt; + return this; + } + + @ApiModelProperty(value = "") + @JsonProperty("updatedAt") + @Valid + public String getUpdatedAt() { + return updatedAt; + } + public void setUpdatedAt(String updatedAt) { + this.updatedAt = updatedAt; + } + + /** + **/ + public InFlowExtensionResponse iconUrl(String iconUrl) { + + this.iconUrl = iconUrl; + return this; + } + + @ApiModelProperty(value = "") + @JsonProperty("iconUrl") + @Valid + public String getIconUrl() { + return iconUrl; + } + public void setIconUrl(String iconUrl) { + this.iconUrl = iconUrl; + } + + /** + **/ + public InFlowExtensionResponse endpoint(EndpointResponse endpoint) { + + this.endpoint = endpoint; + return this; + } + + @ApiModelProperty(value = "") + @JsonProperty("endpoint") + @Valid + public EndpointResponse getEndpoint() { + return endpoint; + } + public void setEndpoint(EndpointResponse endpoint) { + this.endpoint = endpoint; + } + + /** + **/ + public InFlowExtensionResponse accessConfig(AccessConfig accessConfig) { + + this.accessConfig = accessConfig; + return this; + } + + @ApiModelProperty(value = "") + @JsonProperty("accessConfig") + @Valid + public AccessConfig getAccessConfig() { + return accessConfig; + } + public void setAccessConfig(AccessConfig accessConfig) { + this.accessConfig = accessConfig; + } + + /** + **/ + public InFlowExtensionResponse encryption(Encryption encryption) { + + this.encryption = encryption; + return this; + } + + @ApiModelProperty(value = "") + @JsonProperty("encryption") + @Valid + public Encryption getEncryption() { + return encryption; + } + public void setEncryption(Encryption encryption) { + this.encryption = encryption; + } + + + + @Override + public boolean equals(java.lang.Object o) { + + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + InFlowExtensionResponse inFlowExtensionResponse = (InFlowExtensionResponse) o; + return Objects.equals(this.id, inFlowExtensionResponse.id) && + Objects.equals(this.name, inFlowExtensionResponse.name) && + Objects.equals(this.description, inFlowExtensionResponse.description) && + Objects.equals(this.status, inFlowExtensionResponse.status) && + Objects.equals(this.version, inFlowExtensionResponse.version) && + Objects.equals(this.createdAt, inFlowExtensionResponse.createdAt) && + Objects.equals(this.updatedAt, inFlowExtensionResponse.updatedAt) && + Objects.equals(this.iconUrl, inFlowExtensionResponse.iconUrl) && + Objects.equals(this.endpoint, inFlowExtensionResponse.endpoint) && + Objects.equals(this.accessConfig, inFlowExtensionResponse.accessConfig) && + Objects.equals(this.encryption, inFlowExtensionResponse.encryption); + } + + @Override + public int hashCode() { + return Objects.hash(id, name, description, status, version, createdAt, updatedAt, iconUrl, endpoint, accessConfig, encryption); + } + + @Override + public String toString() { + + StringBuilder sb = new StringBuilder(); + sb.append("class InFlowExtensionResponse {\n"); + + sb.append(" id: ").append(toIndentedString(id)).append("\n"); + sb.append(" name: ").append(toIndentedString(name)).append("\n"); + sb.append(" description: ").append(toIndentedString(description)).append("\n"); + sb.append(" status: ").append(toIndentedString(status)).append("\n"); + sb.append(" version: ").append(toIndentedString(version)).append("\n"); + sb.append(" createdAt: ").append(toIndentedString(createdAt)).append("\n"); + sb.append(" updatedAt: ").append(toIndentedString(updatedAt)).append("\n"); + sb.append(" iconUrl: ").append(toIndentedString(iconUrl)).append("\n"); + sb.append(" endpoint: ").append(toIndentedString(endpoint)).append("\n"); + sb.append(" accessConfig: ").append(toIndentedString(accessConfig)).append("\n"); + sb.append(" encryption: ").append(toIndentedString(encryption)).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.flow.management/org.wso2.carbon.identity.api.server.flow.management.v1/src/gen/java/org/wso2/carbon/identity/api/server/flow/management/v1/InFlowExtensionUpdateModel.java b/components/org.wso2.carbon.identity.api.server.flow.management/org.wso2.carbon.identity.api.server.flow.management.v1/src/gen/java/org/wso2/carbon/identity/api/server/flow/management/v1/InFlowExtensionUpdateModel.java new file mode 100644 index 0000000000..443d0a0251 --- /dev/null +++ b/components/org.wso2.carbon.identity.api.server.flow.management/org.wso2.carbon.identity.api.server.flow.management.v1/src/gen/java/org/wso2/carbon/identity/api/server/flow/management/v1/InFlowExtensionUpdateModel.java @@ -0,0 +1,229 @@ +/* + * Copyright (c) 2025, 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.flow.management.v1; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +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.flow.management.v1.AccessConfig; +import org.wso2.carbon.identity.api.server.flow.management.v1.Encryption; +import org.wso2.carbon.identity.api.server.flow.management.v1.EndpointUpdateModel; +import javax.validation.constraints.*; + + +import io.swagger.annotations.*; +import java.util.Objects; +import javax.validation.Valid; +import javax.xml.bind.annotation.*; + +@JsonIgnoreProperties(ignoreUnknown = true) +public class InFlowExtensionUpdateModel { + + private String name; + private String description; + private String iconUrl; + private String version; + private EndpointUpdateModel endpoint; + private AccessConfig accessConfig; + private Encryption encryption; + + /** + **/ + public InFlowExtensionUpdateModel name(String name) { + + this.name = name; + return this; + } + + @ApiModelProperty(value = "") + @JsonProperty("name") + @Valid + public String getName() { + return name; + } + public void setName(String name) { + this.name = name; + } + + /** + **/ + public InFlowExtensionUpdateModel description(String description) { + + this.description = description; + return this; + } + + @ApiModelProperty(value = "") + @JsonProperty("description") + @Valid + public String getDescription() { + return description; + } + public void setDescription(String description) { + this.description = description; + } + + /** + **/ + public InFlowExtensionUpdateModel iconUrl(String iconUrl) { + + this.iconUrl = iconUrl; + return this; + } + + @ApiModelProperty(value = "") + @JsonProperty("iconUrl") + @Valid + public String getIconUrl() { + return iconUrl; + } + public void setIconUrl(String iconUrl) { + this.iconUrl = iconUrl; + } + + /** + **/ + public InFlowExtensionUpdateModel version(String version) { + + this.version = version; + return this; + } + + @ApiModelProperty(value = "") + @JsonProperty("version") + @Valid + public String getVersion() { + return version; + } + public void setVersion(String version) { + this.version = version; + } + + /** + **/ + public InFlowExtensionUpdateModel endpoint(EndpointUpdateModel endpoint) { + + this.endpoint = endpoint; + return this; + } + + @ApiModelProperty(value = "") + @JsonProperty("endpoint") + @Valid + public EndpointUpdateModel getEndpoint() { + return endpoint; + } + public void setEndpoint(EndpointUpdateModel endpoint) { + this.endpoint = endpoint; + } + + /** + **/ + public InFlowExtensionUpdateModel accessConfig(AccessConfig accessConfig) { + + this.accessConfig = accessConfig; + return this; + } + + @ApiModelProperty(value = "") + @JsonProperty("accessConfig") + @Valid + public AccessConfig getAccessConfig() { + return accessConfig; + } + public void setAccessConfig(AccessConfig accessConfig) { + this.accessConfig = accessConfig; + } + + /** + **/ + public InFlowExtensionUpdateModel encryption(Encryption encryption) { + + this.encryption = encryption; + return this; + } + + @ApiModelProperty(value = "") + @JsonProperty("encryption") + @Valid + public Encryption getEncryption() { + return encryption; + } + public void setEncryption(Encryption encryption) { + this.encryption = encryption; + } + + + + @Override + public boolean equals(java.lang.Object o) { + + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + InFlowExtensionUpdateModel inFlowExtensionUpdateModel = (InFlowExtensionUpdateModel) o; + return Objects.equals(this.name, inFlowExtensionUpdateModel.name) && + Objects.equals(this.description, inFlowExtensionUpdateModel.description) && + Objects.equals(this.iconUrl, inFlowExtensionUpdateModel.iconUrl) && + Objects.equals(this.version, inFlowExtensionUpdateModel.version) && + Objects.equals(this.endpoint, inFlowExtensionUpdateModel.endpoint) && + Objects.equals(this.accessConfig, inFlowExtensionUpdateModel.accessConfig) && + Objects.equals(this.encryption, inFlowExtensionUpdateModel.encryption); + } + + @Override + public int hashCode() { + return Objects.hash(name, description, iconUrl, version, endpoint, accessConfig, encryption); + } + + @Override + public String toString() { + + StringBuilder sb = new StringBuilder(); + sb.append("class InFlowExtensionUpdateModel {\n"); + + sb.append(" name: ").append(toIndentedString(name)).append("\n"); + sb.append(" description: ").append(toIndentedString(description)).append("\n"); + sb.append(" iconUrl: ").append(toIndentedString(iconUrl)).append("\n"); + sb.append(" version: ").append(toIndentedString(version)).append("\n"); + sb.append(" endpoint: ").append(toIndentedString(endpoint)).append("\n"); + sb.append(" accessConfig: ").append(toIndentedString(accessConfig)).append("\n"); + sb.append(" encryption: ").append(toIndentedString(encryption)).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.flow.management/org.wso2.carbon.identity.api.server.flow.management.v1/src/gen/java/org/wso2/carbon/identity/api/server/flow/management/v1/Link.java b/components/org.wso2.carbon.identity.api.server.flow.management/org.wso2.carbon.identity.api.server.flow.management.v1/src/gen/java/org/wso2/carbon/identity/api/server/flow/management/v1/Link.java new file mode 100644 index 0000000000..e3d9528e0b --- /dev/null +++ b/components/org.wso2.carbon.identity.api.server.flow.management/org.wso2.carbon.identity.api.server.flow.management.v1/src/gen/java/org/wso2/carbon/identity/api/server/flow/management/v1/Link.java @@ -0,0 +1,173 @@ +/* + * Copyright (c) 2025, 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.flow.management.v1; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import javax.validation.constraints.*; + + +import io.swagger.annotations.*; +import java.util.Objects; +import javax.validation.Valid; +import javax.xml.bind.annotation.*; + +public class Link { + + private String href; + +@XmlType(name="MethodEnum") +@XmlEnum(String.class) +public enum MethodEnum { + + @XmlEnumValue("GET") GET(String.valueOf("GET")); + + + private String value; + + MethodEnum(String v) { + value = v; + } + + public String value() { + return value; + } + + @Override + public String toString() { + return String.valueOf(value); + } + + public static MethodEnum fromValue(String value) { + for (MethodEnum b : MethodEnum.values()) { + if (b.value.equals(value)) { + return b; + } + } + throw new IllegalArgumentException("Unexpected value '" + value + "'"); + } +} + + private MethodEnum method; + private String rel; + + /** + **/ + public Link href(String href) { + + this.href = href; + return this; + } + + @ApiModelProperty(value = "") + @JsonProperty("href") + @Valid + public String getHref() { + return href; + } + public void setHref(String href) { + this.href = href; + } + + /** + **/ + public Link method(MethodEnum method) { + + this.method = method; + return this; + } + + @ApiModelProperty(value = "") + @JsonProperty("method") + @Valid + public MethodEnum getMethod() { + return method; + } + public void setMethod(MethodEnum method) { + this.method = method; + } + + /** + **/ + public Link rel(String rel) { + + this.rel = rel; + return this; + } + + @ApiModelProperty(value = "") + @JsonProperty("rel") + @Valid + public String getRel() { + return rel; + } + public void setRel(String rel) { + this.rel = rel; + } + + + + @Override + public boolean equals(java.lang.Object o) { + + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + Link link = (Link) o; + return Objects.equals(this.href, link.href) && + Objects.equals(this.method, link.method) && + Objects.equals(this.rel, link.rel); + } + + @Override + public int hashCode() { + return Objects.hash(href, method, rel); + } + + @Override + public String toString() { + + StringBuilder sb = new StringBuilder(); + sb.append("class Link {\n"); + + sb.append(" href: ").append(toIndentedString(href)).append("\n"); + sb.append(" method: ").append(toIndentedString(method)).append("\n"); + sb.append(" rel: ").append(toIndentedString(rel)).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.flow.management/org.wso2.carbon.identity.api.server.flow.management.v1/src/main/java/org/wso2/carbon/identity/api/server/flow/management/v1/constants/FlowEndpointConstants.java b/components/org.wso2.carbon.identity.api.server.flow.management/org.wso2.carbon.identity.api.server.flow.management.v1/src/main/java/org/wso2/carbon/identity/api/server/flow/management/v1/constants/FlowEndpointConstants.java index 56c91fbd87..b4f582280d 100644 --- a/components/org.wso2.carbon.identity.api.server.flow.management/org.wso2.carbon.identity.api.server.flow.management.v1/src/main/java/org/wso2/carbon/identity/api/server/flow/management/v1/constants/FlowEndpointConstants.java +++ b/components/org.wso2.carbon.identity.api.server.flow.management/org.wso2.carbon.identity.api.server.flow.management.v1/src/main/java/org/wso2/carbon/identity/api/server/flow/management/v1/constants/FlowEndpointConstants.java @@ -95,7 +95,23 @@ public enum ErrorMessages { ERROR_CODE_REQUIRED_EXECUTOR_MISSING("10013", "Required executor is missing in the flow.", - "The flow must contain the required executors."); + "The flow must contain the required executors."), + + ERROR_CODE_INFLOW_EXTENSION_NOT_FOUND("10020", + "In-Flow Extension not found.", + "No In-Flow Extension was found with the provided ID."), + + ERROR_CODE_INFLOW_EXTENSION_NAME_CONFLICT("10021", + "In-Flow Extension name already in use.", + "An In-Flow Extension with the name '%s' already exists."), + + ERROR_CODE_INVALID_ENDPOINT_AUTH_PROPERTIES("10022", + "Invalid endpoint authentication properties.", + "Required authentication properties are missing or empty for the given authentication type."), + + ERROR_CODE_EMPTY_ENDPOINT_AUTH_PROPERTIES("10023", + "Empty endpoint authentication properties.", + "Endpoint authentication properties cannot be empty."); private final String code; private final String message; @@ -153,6 +169,7 @@ public static class Executors { public static final String MAGIC_LINK_EXECUTOR = "MagicLinkExecutor"; public static final String CONFIRMATION_CODE_VALIDATION_EXECUTOR = "ConfirmationCodeValidationExecutor"; public static final String USER_PROVISIONING_EXECUTOR = "UserProvisioningExecutor"; + public static final String IN_FLOW_EXTENSION_EXECUTOR = "InFlowExtensionExecutor"; } /** diff --git a/components/org.wso2.carbon.identity.api.server.flow.management/org.wso2.carbon.identity.api.server.flow.management.v1/src/main/java/org/wso2/carbon/identity/api/server/flow/management/v1/core/ServerFlowMgtService.java b/components/org.wso2.carbon.identity.api.server.flow.management/org.wso2.carbon.identity.api.server.flow.management.v1/src/main/java/org/wso2/carbon/identity/api/server/flow/management/v1/core/ServerFlowMgtService.java index f8a51b9069..0b2e13f0c2 100644 --- a/components/org.wso2.carbon.identity.api.server.flow.management/org.wso2.carbon.identity.api.server.flow.management.v1/src/main/java/org/wso2/carbon/identity/api/server/flow/management/v1/core/ServerFlowMgtService.java +++ b/components/org.wso2.carbon.identity.api.server.flow.management/org.wso2.carbon.identity.api.server.flow.management.v1/src/main/java/org/wso2/carbon/identity/api/server/flow/management/v1/core/ServerFlowMgtService.java @@ -19,17 +19,31 @@ package org.wso2.carbon.identity.api.server.flow.management.v1.core; import org.wso2.carbon.context.PrivilegedCarbonContext; +import org.wso2.carbon.identity.action.management.api.exception.ActionMgtException; +import org.wso2.carbon.identity.action.management.api.model.Action; +import org.wso2.carbon.identity.action.management.api.service.ActionManagementService; import org.wso2.carbon.identity.api.server.flow.management.v1.FlowConfig; import org.wso2.carbon.identity.api.server.flow.management.v1.FlowConfigPatchModel; import org.wso2.carbon.identity.api.server.flow.management.v1.FlowMetaResponse; import org.wso2.carbon.identity.api.server.flow.management.v1.FlowRequest; import org.wso2.carbon.identity.api.server.flow.management.v1.FlowResponse; +import org.wso2.carbon.identity.api.server.flow.management.v1.InFlowExtensionBasicResponse; +import org.wso2.carbon.identity.api.server.flow.management.v1.InFlowExtensionContextTreeResponse; +import org.wso2.carbon.identity.api.server.flow.management.v1.InFlowExtensionModel; +import org.wso2.carbon.identity.api.server.flow.management.v1.InFlowExtensionNameCheckRequest; +import org.wso2.carbon.identity.api.server.flow.management.v1.InFlowExtensionNameCheckResponse; +import org.wso2.carbon.identity.api.server.flow.management.v1.InFlowExtensionResponse; +import org.wso2.carbon.identity.api.server.flow.management.v1.InFlowExtensionUpdateModel; import org.wso2.carbon.identity.api.server.flow.management.v1.Step; import org.wso2.carbon.identity.api.server.flow.management.v1.response.handlers.AbstractMetaResponseHandler; import org.wso2.carbon.identity.api.server.flow.management.v1.response.handlers.AskPasswordFlowMetaHandler; import org.wso2.carbon.identity.api.server.flow.management.v1.response.handlers.PasswordRecoveryFlowMetaHandler; import org.wso2.carbon.identity.api.server.flow.management.v1.response.handlers.RegistrationFlowMetaHandler; +import org.wso2.carbon.identity.api.server.flow.management.v1.utils.InFlowExtensionContextTreeMapper; +import org.wso2.carbon.identity.api.server.flow.management.v1.utils.InFlowExtensionMapper; import org.wso2.carbon.identity.api.server.flow.management.v1.utils.Utils; +import org.wso2.carbon.identity.flow.extensions.metadata.InFlowExtensionContextTreeMetadata; +import org.wso2.carbon.identity.flow.extensions.metadata.InFlowExtensionContextTreeService; import org.wso2.carbon.identity.flow.mgt.Constants; import org.wso2.carbon.identity.flow.mgt.FlowMgtService; import org.wso2.carbon.identity.flow.mgt.exception.FlowMgtFrameworkException; @@ -52,11 +66,17 @@ */ public class ServerFlowMgtService { + private static final String IN_FLOW_EXTENSION_ACTION_TYPE = + Action.ActionTypes.FLOW_EXTENSIONS.getPathParam(); + private final FlowMgtService flowMgtService; + private final ActionManagementService actionManagementService; - public ServerFlowMgtService(FlowMgtService flowMgtService) { + public ServerFlowMgtService(FlowMgtService flowMgtService, + ActionManagementService actionManagementService) { this.flowMgtService = flowMgtService; + this.actionManagementService = actionManagementService; } /** @@ -96,6 +116,30 @@ public FlowMetaResponse getFlowMeta(String flowType) { return metaResponseHandler.createResponse(); } + /** + * Retrieve the controlled In-Flow Extension context tree for the given flow type. When + * {@code flowType} is null/blank, the default tree is returned. The tree is filtered + * server-side per the {@code [identity.in_flow_extension.context.*]} whitelist in + * {@code deployment.toml} so the Console UI only offers paths the deployment allows. + * + * @param flowType optional flow type (null → default tree). + * @return the tree response. + */ + public InFlowExtensionContextTreeResponse getInFlowExtensionContextTree(String flowType) { + + String resolvedFlowType = (flowType != null && !flowType.trim().isEmpty()) ? flowType : null; + if (resolvedFlowType != null) { + // Reuse the same flow-type validation used by the other endpoints. + Utils.validateFlowType(resolvedFlowType); + } + // Goes through the engine's PUBLIC metadata service rather than reaching into the + // engine's internal DataHolder — the latter lives in a Private-Package and isn't + // visible to other OSGi bundles at runtime. + InFlowExtensionContextTreeMetadata metadata = + InFlowExtensionContextTreeService.getInstance().buildContextTree(resolvedFlowType); + return InFlowExtensionContextTreeMapper.toResponse(metadata); + } + /** * Update the flow. * @@ -219,6 +263,126 @@ public FlowConfig updateFlowConfig(FlowConfigPatchModel flowConfigPatchModel) { } } + /** + * Create a new InFlow extension action. + * + * @param model the create request model. + * @return the full response of the created extension. + */ + public InFlowExtensionResponse createInFlowExtension(InFlowExtensionModel model) { + + try { + Action domainAction = InFlowExtensionMapper.toInFlowExtensionAction(model); + String tenantDomain = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain(); + Action created = actionManagementService.addAction( + IN_FLOW_EXTENSION_ACTION_TYPE, domainAction, tenantDomain); + return InFlowExtensionMapper.toInFlowExtensionResponse(created); + } catch (ActionMgtException e) { + throw Utils.handleActionMgtException(e); + } + } + + /** + * List all InFlow extension actions for the current tenant. + * + * @return list of basic response items. + */ + public List getInFlowExtensions() { + + try { + String tenantDomain = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain(); + List actions = actionManagementService.getActionsByActionType( + IN_FLOW_EXTENSION_ACTION_TYPE, tenantDomain); + return actions.stream() + .map(InFlowExtensionMapper::toInFlowExtensionBasicResponse) + .collect(Collectors.toList()); + } catch (ActionMgtException e) { + throw Utils.handleActionMgtException(e); + } + } + + /** + * Get a single InFlow extension by its ID. + * + * @param extensionId the action ID. + * @return the full response model. + */ + public InFlowExtensionResponse getInFlowExtensionById(String extensionId) { + + try { + String tenantDomain = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain(); + Action action = actionManagementService.getActionByActionId( + IN_FLOW_EXTENSION_ACTION_TYPE, extensionId, tenantDomain); + return InFlowExtensionMapper.toInFlowExtensionResponse(action); + } catch (ActionMgtException e) { + throw Utils.handleActionMgtException(e); + } + } + + /** + * Update (PATCH) an InFlow extension. + * + * @param extensionId the action ID to update. + * @param model the update request model. + * @return the full updated response model. + */ + public InFlowExtensionResponse updateInFlowExtension(String extensionId, + InFlowExtensionUpdateModel model) { + + try { + Action domainAction = InFlowExtensionMapper.toInFlowExtensionAction(model); + String tenantDomain = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain(); + Action updated = actionManagementService.updateAction( + IN_FLOW_EXTENSION_ACTION_TYPE, extensionId, domainAction, tenantDomain); + return InFlowExtensionMapper.toInFlowExtensionResponse(updated); + } catch (ActionMgtException e) { + throw Utils.handleActionMgtException(e); + } + } + + /** + * Delete an InFlow extension by its ID. + * + * @param extensionId the action ID to delete. + */ + public void deleteInFlowExtension(String extensionId) { + + try { + String tenantDomain = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain(); + actionManagementService.deleteAction( + IN_FLOW_EXTENSION_ACTION_TYPE, extensionId, tenantDomain); + } catch (ActionMgtException e) { + throw Utils.handleActionMgtException(e); + } + } + + /** + * Check whether the given InFlow extension name is available (unique) for the current tenant. + * When {@code request.getExcludeId()} is non-null the check excludes that action ID (update + * scenario). + * + * @param request the name-check request model. + * @return a response model with {@code available = true/false}. + */ + public InFlowExtensionNameCheckResponse checkInFlowExtensionName( + InFlowExtensionNameCheckRequest request) { + + try { + String tenantDomain = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain(); + // Pass excludeId as-is; null or empty means creation scenario (no exclusion). + String excludeId = (request.getExcludeId() != null && !request.getExcludeId().isEmpty()) + ? request.getExcludeId() : null; + List existing = actionManagementService.getActionsByActionType( + IN_FLOW_EXTENSION_ACTION_TYPE, tenantDomain); + boolean available = existing.stream() + .filter(a -> excludeId == null || !excludeId.equals(a.getId())) + .noneMatch(a -> request.getName().equals(a.getName())); + return new InFlowExtensionNameCheckResponse().available(available); + } catch (ActionMgtException e) { + throw Utils.handleActionMgtException(e); + } + } + /** * Validate the flow type and steps. * diff --git a/components/org.wso2.carbon.identity.api.server.flow.management/org.wso2.carbon.identity.api.server.flow.management.v1/src/main/java/org/wso2/carbon/identity/api/server/flow/management/v1/factories/ServerFlowMgtServiceFactory.java b/components/org.wso2.carbon.identity.api.server.flow.management/org.wso2.carbon.identity.api.server.flow.management.v1/src/main/java/org/wso2/carbon/identity/api/server/flow/management/v1/factories/ServerFlowMgtServiceFactory.java index b1708b11a4..d599ee1865 100644 --- a/components/org.wso2.carbon.identity.api.server.flow.management/org.wso2.carbon.identity.api.server.flow.management.v1/src/main/java/org/wso2/carbon/identity/api/server/flow/management/v1/factories/ServerFlowMgtServiceFactory.java +++ b/components/org.wso2.carbon.identity.api.server.flow.management/org.wso2.carbon.identity.api.server.flow.management.v1/src/main/java/org/wso2/carbon/identity/api/server/flow/management/v1/factories/ServerFlowMgtServiceFactory.java @@ -19,6 +19,7 @@ package org.wso2.carbon.identity.api.server.flow.management.v1.factories; +import org.wso2.carbon.identity.action.management.api.service.ActionManagementService; import org.wso2.carbon.identity.api.server.flow.management.common.FlowMgtServiceHolder; import org.wso2.carbon.identity.api.server.flow.management.v1.core.ServerFlowMgtService; import org.wso2.carbon.identity.flow.mgt.FlowMgtService; @@ -38,7 +39,14 @@ public class ServerFlowMgtServiceFactory { throw new IllegalStateException("FlowMgtService is not available from OSGi context."); } - SERVICE = new ServerFlowMgtService(flowMgtService); + ActionManagementService actionManagementService = FlowMgtServiceHolder + .getActionManagementService(); + + if (actionManagementService == null) { + throw new IllegalStateException("ActionManagementService is not available from OSGi context."); + } + + SERVICE = new ServerFlowMgtService(flowMgtService, actionManagementService); } /** diff --git a/components/org.wso2.carbon.identity.api.server.flow.management/org.wso2.carbon.identity.api.server.flow.management.v1/src/main/java/org/wso2/carbon/identity/api/server/flow/management/v1/impl/FlowApiServiceImpl.java b/components/org.wso2.carbon.identity.api.server.flow.management/org.wso2.carbon.identity.api.server.flow.management.v1/src/main/java/org/wso2/carbon/identity/api/server/flow/management/v1/impl/FlowApiServiceImpl.java index 8be30fdc78..254197874b 100644 --- a/components/org.wso2.carbon.identity.api.server.flow.management/org.wso2.carbon.identity.api.server.flow.management.v1/src/main/java/org/wso2/carbon/identity/api/server/flow/management/v1/impl/FlowApiServiceImpl.java +++ b/components/org.wso2.carbon.identity.api.server.flow.management/org.wso2.carbon.identity.api.server.flow.management.v1/src/main/java/org/wso2/carbon/identity/api/server/flow/management/v1/impl/FlowApiServiceImpl.java @@ -18,6 +18,7 @@ package org.wso2.carbon.identity.api.server.flow.management.v1.impl; +import org.wso2.carbon.identity.api.server.common.ContextLoader; import org.wso2.carbon.identity.api.server.flow.management.v1.FlowApiService; import org.wso2.carbon.identity.api.server.flow.management.v1.FlowConfig; import org.wso2.carbon.identity.api.server.flow.management.v1.FlowConfigPatchModel; @@ -28,15 +29,23 @@ import org.wso2.carbon.identity.api.server.flow.management.v1.FlowMetaResponse; import org.wso2.carbon.identity.api.server.flow.management.v1.FlowRequest; import org.wso2.carbon.identity.api.server.flow.management.v1.FlowResponse; +import org.wso2.carbon.identity.api.server.flow.management.v1.InFlowExtensionBasicResponse; +import org.wso2.carbon.identity.api.server.flow.management.v1.InFlowExtensionModel; +import org.wso2.carbon.identity.api.server.flow.management.v1.InFlowExtensionNameCheckRequest; +import org.wso2.carbon.identity.api.server.flow.management.v1.InFlowExtensionNameCheckResponse; +import org.wso2.carbon.identity.api.server.flow.management.v1.InFlowExtensionResponse; +import org.wso2.carbon.identity.api.server.flow.management.v1.InFlowExtensionUpdateModel; import org.wso2.carbon.identity.api.server.flow.management.v1.core.FlowAIServiceCore; import org.wso2.carbon.identity.api.server.flow.management.v1.core.ServerFlowMgtService; import org.wso2.carbon.identity.api.server.flow.management.v1.factories.FlowAIServiceFactory; import org.wso2.carbon.identity.api.server.flow.management.v1.factories.ServerFlowMgtServiceFactory; - +import java.net.URI; import java.util.List; import javax.ws.rs.core.Response; +import static org.wso2.carbon.identity.api.server.common.Constants.V1_API_PATH_COMPONENT; + /** * Implementation of the Flow API. */ @@ -54,6 +63,22 @@ public FlowApiServiceImpl() { throw new RuntimeException("Error occurred while initiating flow management service.", e); } } + @Override + public Response checkInFlowExtensionName(InFlowExtensionNameCheckRequest inFlowExtensionNameCheckRequest) { + + InFlowExtensionNameCheckResponse result = + flowMgtService.checkInFlowExtensionName(inFlowExtensionNameCheckRequest); + return Response.ok().entity(result).build(); + } + + @Override + public Response createInFlowExtension(InFlowExtensionModel inFlowExtensionModel) { + + InFlowExtensionResponse created = flowMgtService.createInFlowExtension(inFlowExtensionModel); + URI location = ContextLoader.buildURIForHeader( + V1_API_PATH_COMPONENT + "/flow/in-flow-extensions/" + created.getId()); + return Response.created(location).entity(created).build(); + } @Override public Response deleteFlow(String flowType) { @@ -62,6 +87,13 @@ public Response deleteFlow(String flowType) { return Response.noContent().build(); } + @Override + public Response deleteInFlowExtension(String extensionId) { + + flowMgtService.deleteInFlowExtension(extensionId); + return Response.noContent().build(); + } + @Override public Response generateFlow(FlowGenerateRequest flowGenerateRequest) { @@ -111,6 +143,27 @@ public Response getFlowMeta(String flowType) { return Response.ok().entity(flowMeta).build(); } + @Override + public Response getInFlowExtensionById(String extensionId) { + + InFlowExtensionResponse extension = flowMgtService.getInFlowExtensionById(extensionId); + return Response.ok().entity(extension).build(); + } + + @Override + public Response getInFlowExtensionContextTree(String flowType) { + + return Response.ok().entity( + flowMgtService.getInFlowExtensionContextTree(flowType)).build(); + } + + @Override + public Response getInFlowExtensions() { + + List extensions = flowMgtService.getInFlowExtensions(); + return Response.ok().entity(extensions).build(); + } + @Override public Response updateFlow(FlowRequest flowRequest) { @@ -124,4 +177,13 @@ public Response updateFlowConfig(FlowConfigPatchModel flowConfigPatchModel) { FlowConfig flowConfig = flowMgtService.updateFlowConfig(flowConfigPatchModel); return Response.ok().entity(flowConfig).build(); } + + @Override + public Response updateInFlowExtension(String extensionId, + InFlowExtensionUpdateModel inFlowExtensionUpdateModel) { + + InFlowExtensionResponse updated = + flowMgtService.updateInFlowExtension(extensionId, inFlowExtensionUpdateModel); + return Response.ok().entity(updated).build(); + } } diff --git a/components/org.wso2.carbon.identity.api.server.flow.management/org.wso2.carbon.identity.api.server.flow.management.v1/src/main/java/org/wso2/carbon/identity/api/server/flow/management/v1/response/handlers/AbstractMetaResponseHandler.java b/components/org.wso2.carbon.identity.api.server.flow.management/org.wso2.carbon.identity.api.server.flow.management.v1/src/main/java/org/wso2/carbon/identity/api/server/flow/management/v1/response/handlers/AbstractMetaResponseHandler.java index 7c6d3a13c4..15d30e1e22 100644 --- a/components/org.wso2.carbon.identity.api.server.flow.management/org.wso2.carbon.identity.api.server.flow.management.v1/src/main/java/org/wso2/carbon/identity/api/server/flow/management/v1/response/handlers/AbstractMetaResponseHandler.java +++ b/components/org.wso2.carbon.identity.api.server.flow.management/org.wso2.carbon.identity.api.server.flow.management.v1/src/main/java/org/wso2/carbon/identity/api/server/flow/management/v1/response/handlers/AbstractMetaResponseHandler.java @@ -18,17 +18,23 @@ package org.wso2.carbon.identity.api.server.flow.management.v1.response.handlers; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; import org.wso2.carbon.context.PrivilegedCarbonContext; +import org.wso2.carbon.identity.action.management.api.exception.ActionMgtException; +import org.wso2.carbon.identity.action.management.api.model.Action; import org.wso2.carbon.identity.api.server.flow.management.common.FlowMgtServiceHolder; import org.wso2.carbon.identity.api.server.flow.management.v1.AttributeMetadata; import org.wso2.carbon.identity.api.server.flow.management.v1.ExecutorConnections; import org.wso2.carbon.identity.api.server.flow.management.v1.FlowMetaResponse; +import org.wso2.carbon.identity.api.server.flow.management.v1.InFlowExtensionConnectionInfo; import org.wso2.carbon.identity.api.server.flow.management.v1.constants.FlowEndpointConstants; import org.wso2.carbon.identity.api.server.flow.management.v1.utils.Utils; import org.wso2.carbon.identity.application.common.model.IdentityProvider; import org.wso2.carbon.identity.claim.metadata.mgt.ClaimMetadataManagementService; import org.wso2.carbon.identity.claim.metadata.mgt.exception.ClaimMetadataException; import org.wso2.carbon.identity.claim.metadata.mgt.model.LocalClaim; +import org.wso2.carbon.identity.flow.extensions.model.InFlowExtensionAction; import org.wso2.carbon.identity.flow.mgt.exception.FlowMgtClientException; import org.wso2.carbon.identity.multi.attribute.login.constants.MultiAttributeLoginConstants; import org.wso2.carbon.idp.mgt.IdentityProviderManagementException; @@ -51,6 +57,7 @@ import static org.wso2.carbon.identity.api.server.flow.management.v1.constants.FlowEndpointConstants.Executors.FACEBOOK_EXECUTOR; import static org.wso2.carbon.identity.api.server.flow.management.v1.constants.FlowEndpointConstants.Executors.GITHUB_EXECUTOR; import static org.wso2.carbon.identity.api.server.flow.management.v1.constants.FlowEndpointConstants.Executors.GOOGLE_EXECUTOR; +import static org.wso2.carbon.identity.api.server.flow.management.v1.constants.FlowEndpointConstants.Executors.IN_FLOW_EXTENSION_EXECUTOR; import static org.wso2.carbon.identity.api.server.flow.management.v1.constants.FlowEndpointConstants.Executors.MAGIC_LINK_EXECUTOR; import static org.wso2.carbon.identity.api.server.flow.management.v1.constants.FlowEndpointConstants.Executors.OFFICE365_EXECUTOR; import static org.wso2.carbon.identity.api.server.flow.management.v1.constants.FlowEndpointConstants.Executors.OPENID_CONNECT_EXECUTOR; @@ -71,6 +78,7 @@ */ public abstract class AbstractMetaResponseHandler { + private static final Log log = LogFactory.getLog(AbstractMetaResponseHandler.class); private static final String MULTI_ATTRIBUTE_LOGIN_ENABLED = "multiAttributeLoginEnabled"; /** @@ -110,6 +118,7 @@ public List getSupportedExecutors() { supportedExecutors.add(SMS_OTP_EXECUTOR); supportedExecutors.add(MAGIC_LINK_EXECUTOR); supportedExecutors.add(USER_PROVISIONING_EXECUTOR); + supportedExecutors.add(IN_FLOW_EXTENSION_EXECUTOR); return supportedExecutors; } @@ -149,6 +158,7 @@ public FlowMetaResponse createResponse() { response.setSupportedExecutors(getSupportedExecutors()); response.setConnectorConfigs(getConnectorConfigs()); response.setExecutorConnections(getExecutorConnections()); + response.setInflowExtensionConnections(getInflowExtensionConnections()); response.setSupportedFlowCompletionConfigs(getSupportedFlowCompletionConfigs()); return response; } @@ -217,6 +227,41 @@ protected List getLoginInputFields() { return fields; } + /** + * Returns the list of InFlow extension connection info for this flow. + * Fetches all ACTIVE InFlow Extension actions from ActionManagementService. + * + * @return list of InFlow extension connections, or empty list if none. + */ + protected List getInflowExtensionConnections() { + + String tenantDomain = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain(); + try { + List actions = FlowMgtServiceHolder.getActionManagementService() + .getActionsByActionType(Action.ActionTypes.FLOW_EXTENSIONS.getPathParam(), tenantDomain); + if (actions == null) { + return Collections.emptyList(); + } + List connections = new ArrayList<>(); + for (Action action : actions) { + if (!Action.Status.ACTIVE.equals(action.getStatus())) { + continue; + } + InFlowExtensionConnectionInfo info = new InFlowExtensionConnectionInfo() + .actionId(action.getId()) + .name(action.getName()); + if (action instanceof InFlowExtensionAction) { + info.iconUrl(((InFlowExtensionAction) action).getIconUrl()); + } + connections.add(info); + } + return connections; + } catch (ActionMgtException e) { + log.warn("Failed to fetch InFlow Extension connections for flow meta.", e); + return Collections.emptyList(); + } + } + protected List getExecutorConnections() { try { @@ -311,4 +356,5 @@ private AttributeMetadata createUserIdentifierMeta() { meta.setReadOnly(true); return meta; } + } diff --git a/components/org.wso2.carbon.identity.api.server.flow.management/org.wso2.carbon.identity.api.server.flow.management.v1/src/main/java/org/wso2/carbon/identity/api/server/flow/management/v1/utils/InFlowExtensionContextTreeMapper.java b/components/org.wso2.carbon.identity.api.server.flow.management/org.wso2.carbon.identity.api.server.flow.management.v1/src/main/java/org/wso2/carbon/identity/api/server/flow/management/v1/utils/InFlowExtensionContextTreeMapper.java new file mode 100644 index 0000000000..be61104d47 --- /dev/null +++ b/components/org.wso2.carbon.identity.api.server.flow.management/org.wso2.carbon.identity.api.server.flow.management.v1/src/main/java/org/wso2/carbon/identity/api/server/flow/management/v1/utils/InFlowExtensionContextTreeMapper.java @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2026, 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.flow.management.v1.utils; + +import org.wso2.carbon.identity.api.server.flow.management.v1.InFlowExtensionContextTreeNode; +import org.wso2.carbon.identity.api.server.flow.management.v1.InFlowExtensionContextTreeResponse; +import org.wso2.carbon.identity.flow.extensions.metadata.InFlowExtensionContextTreeMetadata; + +import java.util.List; +import java.util.stream.Collectors; + +/** + * Maps the engine-side {@link InFlowExtensionContextTreeMetadata} DTO to the API-side + * {@link InFlowExtensionContextTreeResponse} model. A boundary-crossing copy keeps the + * engine module independent of the API server's swagger-generated models. + */ +public final class InFlowExtensionContextTreeMapper { + + private InFlowExtensionContextTreeMapper() { + + } + + public static InFlowExtensionContextTreeResponse toResponse(InFlowExtensionContextTreeMetadata metadata) { + + InFlowExtensionContextTreeResponse response = new InFlowExtensionContextTreeResponse() + .flowType(metadata.getFlowType()) + .redirectionEnabled(metadata.isRedirectionEnabled()) + .allowReadOnlyClaimsModification(metadata.isAllowReadOnlyClaimsModification()); + + response.setContextTree(toApiNodes(metadata.getContextTree())); + return response; + } + + private static List toApiNodes( + List nodes) { + + if (nodes == null) { + return null; + } + return nodes.stream() + .map(InFlowExtensionContextTreeMapper::toApiNode) + .collect(Collectors.toList()); + } + + private static InFlowExtensionContextTreeNode toApiNode( + org.wso2.carbon.identity.flow.extensions.metadata + .InFlowExtensionContextTreeNode node) { + + InFlowExtensionContextTreeNode out = new InFlowExtensionContextTreeNode() + .key(node.getKey()) + .title(node.getTitle()) + .path(node.getPath()) + .dataType(node.getDataType()) + .nodeType(node.getNodeType() != null + ? InFlowExtensionContextTreeNode.NodeTypeEnum.fromValue(node.getNodeType()) : null) + .readOnly(node.isReadOnly()) + .replaceable(node.isReplaceable()) + .dynamicEntryAllowed(node.isDynamicEntryAllowed()) + .dynamicEntryType(node.getDynamicEntryType()); + + if (node.getAllowedOperations() != null) { + out.setAllowedOperations(node.getAllowedOperations().stream() + .map(InFlowExtensionContextTreeNode.AllowedOperationsEnum::fromValue) + .collect(java.util.stream.Collectors.toList())); + } + if (node.getChildren() != null) { + out.setChildren(toApiNodes(node.getChildren())); + } + return out; + } +} diff --git a/components/org.wso2.carbon.identity.api.server.flow.management/org.wso2.carbon.identity.api.server.flow.management.v1/src/main/java/org/wso2/carbon/identity/api/server/flow/management/v1/utils/InFlowExtensionMapper.java b/components/org.wso2.carbon.identity.api.server.flow.management/org.wso2.carbon.identity.api.server.flow.management.v1/src/main/java/org/wso2/carbon/identity/api/server/flow/management/v1/utils/InFlowExtensionMapper.java new file mode 100644 index 0000000000..f2c1bf6846 --- /dev/null +++ b/components/org.wso2.carbon.identity.api.server.flow.management/org.wso2.carbon.identity.api.server.flow.management.v1/src/main/java/org/wso2/carbon/identity/api/server/flow/management/v1/utils/InFlowExtensionMapper.java @@ -0,0 +1,412 @@ +/* + * Copyright (c) 2025, 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.flow.management.v1.utils; + +import org.apache.commons.lang.StringUtils; +import org.wso2.carbon.identity.action.management.api.exception.ActionMgtClientException; +import org.wso2.carbon.identity.action.management.api.model.Action; +import org.wso2.carbon.identity.action.management.api.model.Authentication; +import org.wso2.carbon.identity.action.management.api.model.EndpointConfig; +import org.wso2.carbon.identity.api.server.flow.management.v1.AccessConfig; +import org.wso2.carbon.identity.api.server.flow.management.v1.AuthenticationTypeResponse; +import org.wso2.carbon.identity.api.server.flow.management.v1.ContextPath; +import org.wso2.carbon.identity.api.server.flow.management.v1.Encryption; +import org.wso2.carbon.identity.api.server.flow.management.v1.Endpoint; +import org.wso2.carbon.identity.api.server.flow.management.v1.EndpointResponse; +import org.wso2.carbon.identity.api.server.flow.management.v1.EndpointUpdateModel; +import org.wso2.carbon.identity.api.server.flow.management.v1.InFlowExtensionBasicResponse; +import org.wso2.carbon.identity.api.server.flow.management.v1.InFlowExtensionModel; +import org.wso2.carbon.identity.api.server.flow.management.v1.InFlowExtensionResponse; +import org.wso2.carbon.identity.api.server.flow.management.v1.InFlowExtensionUpdateModel; +import org.wso2.carbon.identity.certificate.management.model.Certificate; +import org.wso2.carbon.identity.flow.extensions.model.InFlowExtensionAction; + +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +import static org.wso2.carbon.identity.api.server.flow.management.v1.constants.FlowEndpointConstants.ErrorMessages.ERROR_CODE_EMPTY_ENDPOINT_AUTH_PROPERTIES; +import static org.wso2.carbon.identity.api.server.flow.management.v1.constants.FlowEndpointConstants.ErrorMessages.ERROR_CODE_INVALID_ENDPOINT_AUTH_PROPERTIES; + +/** + * Mapper utility for translating between the flow-management API models and the + * {@link InFlowExtensionAction} domain model. + *

+ * All methods are static; this class has no OSGi dependency. + *

+ */ +public final class InFlowExtensionMapper { + + private InFlowExtensionMapper() { + + } + + // ------------------------------------------------------------------------- + // API model → Domain model (create) + // ------------------------------------------------------------------------- + + /** + * Convert a create-request {@link InFlowExtensionModel} to an {@link InFlowExtensionAction} + * ready to be passed to {@code ActionManagementService#addAction}. + * + * @param model the API create model. + * @return domain action for persistence. + * @throws ActionMgtClientException if endpoint authentication properties are invalid. + */ + public static Action toInFlowExtensionAction(InFlowExtensionModel model) + throws ActionMgtClientException { + + EndpointConfig endpointConfig = toEndpointConfig(model.getEndpoint()); + + org.wso2.carbon.identity.flow.extensions.model.AccessConfig accessConfig = + toEngineAccessConfig(model.getAccessConfig()); + org.wso2.carbon.identity.flow.extensions.model.Encryption encryption = + toEngineEncryption(model.getEncryption()); + + Action baseAction = new Action.ActionRequestBuilder() + .name(model.getName()) + .description(model.getDescription()) + .endpoint(endpointConfig) + .build(); + + return new InFlowExtensionAction.RequestBuilder(baseAction) + .accessConfig(accessConfig) + .encryption(encryption) + .iconUrl(model.getIconUrl()) + .build(); + } + + // ------------------------------------------------------------------------- + // API model → Domain model (update / PATCH) + // ------------------------------------------------------------------------- + + /** + * Convert an update-request {@link InFlowExtensionUpdateModel} to an + * {@link InFlowExtensionAction} ready to be passed to + * {@code ActionManagementService#updateAction}. + * Only non-null fields are set; null fields are ignored (PATCH semantics). + * + * @param model the API update model. + * @return domain action carrying only the fields that should be updated. + * @throws ActionMgtClientException if endpoint authentication properties are invalid. + */ + public static Action toInFlowExtensionAction(InFlowExtensionUpdateModel model) + throws ActionMgtClientException { + + EndpointConfig endpointConfig = null; + if (model.getEndpoint() != null) { + endpointConfig = toEndpointConfigFromUpdate(model.getEndpoint()); + } + + Action baseAction = new Action.ActionRequestBuilder() + .name(model.getName()) + .description(model.getDescription()) + .actionVersion(model.getVersion()) + .endpoint(endpointConfig) + .build(); + + org.wso2.carbon.identity.flow.extensions.model.AccessConfig accessConfig = + toEngineAccessConfig(model.getAccessConfig()); + org.wso2.carbon.identity.flow.extensions.model.Encryption encryption = + toEngineEncryption(model.getEncryption()); + + return new InFlowExtensionAction.RequestBuilder(baseAction) + .accessConfig(accessConfig) + .encryption(encryption) + .iconUrl(model.getIconUrl()) + .build(); + } + + // ------------------------------------------------------------------------- + // Domain model → API response (full) + // ------------------------------------------------------------------------- + + /** + * Convert an {@link Action} (expected to be an {@link InFlowExtensionAction}) to a full + * {@link InFlowExtensionResponse}. + * + * @param action the domain action returned by the service layer. + * @return API response model. + */ + public static InFlowExtensionResponse toInFlowExtensionResponse(Action action) { + + InFlowExtensionAction ext = (action instanceof InFlowExtensionAction) + ? (InFlowExtensionAction) action : null; + + InFlowExtensionResponse response = new InFlowExtensionResponse() + .id(action.getId()) + .name(action.getName()) + .description(action.getDescription()) + .status(InFlowExtensionResponse.StatusEnum.valueOf(action.getStatus().name())) + .version(action.getActionVersion()) + .createdAt(action.getCreatedAt() != null + ? action.getCreatedAt().toInstant().toString() : null) + .updatedAt(action.getUpdatedAt() != null + ? action.getUpdatedAt().toInstant().toString() : null) + .endpoint(toEndpointResponse(action.getEndpoint())); + + if (ext != null) { + response.accessConfig(toApiAccessConfig(ext.getAccessConfig())); + if (ext.getEncryption() != null) { + response.encryption(toApiEncryption(ext.getEncryption())); + } + response.iconUrl(ext.getIconUrl()); + } + return response; + } + + // ------------------------------------------------------------------------- + // Domain model → API response (list item) + // ------------------------------------------------------------------------- + + /** + * Convert an {@link Action} to a lightweight {@link InFlowExtensionBasicResponse} for list + * responses. + * + * @param action the domain action. + * @return API list-item model. + */ + public static InFlowExtensionBasicResponse toInFlowExtensionBasicResponse(Action action) { + + InFlowExtensionBasicResponse response = new InFlowExtensionBasicResponse() + .id(action.getId()) + .name(action.getName()) + .description(action.getDescription()) + .status(InFlowExtensionBasicResponse.StatusEnum.valueOf(action.getStatus().name())) + .version(action.getActionVersion()) + .createdAt(action.getCreatedAt() != null + ? action.getCreatedAt().toInstant().toString() : null) + .updatedAt(action.getUpdatedAt() != null + ? action.getUpdatedAt().toInstant().toString() : null); + if (action instanceof InFlowExtensionAction) { + response.iconUrl(((InFlowExtensionAction) action).getIconUrl()); + } + return response; + } + + // ------------------------------------------------------------------------- + // Private helpers — Endpoint + // ------------------------------------------------------------------------- + + private static EndpointConfig toEndpointConfig(Endpoint endpoint) + throws ActionMgtClientException { + + Authentication authentication = buildAuthentication( + Authentication.Type.valueOfName(endpoint.getAuthentication().getType().toString()), + endpoint.getAuthentication().getProperties()); + + return new EndpointConfig.EndpointConfigBuilder() + .uri(endpoint.getUri()) + .authentication(authentication) + .allowedHeaders(endpoint.getAllowedHeaders()) + .build(); + } + + private static EndpointConfig toEndpointConfigFromUpdate(EndpointUpdateModel endpoint) + throws ActionMgtClientException { + + Authentication authentication = null; + if (endpoint.getAuthentication() != null) { + authentication = buildAuthentication( + Authentication.Type.valueOfName( + endpoint.getAuthentication().getType().toString()), + endpoint.getAuthentication().getProperties()); + } + + return new EndpointConfig.EndpointConfigBuilder() + .uri(endpoint.getUri()) + .authentication(authentication) + .allowedHeaders(endpoint.getAllowedHeaders()) + .build(); + } + + private static EndpointResponse toEndpointResponse(EndpointConfig endpointConfig) { + + if (endpointConfig == null) { + return null; + } + return new EndpointResponse() + .uri(endpointConfig.getUri()) + .authentication(new AuthenticationTypeResponse() + .type(AuthenticationTypeResponse.TypeEnum.valueOf( + endpointConfig.getAuthentication().getType().toString()))) + .allowedHeaders(endpointConfig.getAllowedHeaders()); + } + + // ------------------------------------------------------------------------- + // Private helpers — Authentication + // ------------------------------------------------------------------------- + + private static Authentication buildAuthentication(Authentication.Type authType, + Map props) + throws ActionMgtClientException { + + switch (authType) { + case BASIC: + String username = getRequiredStringProp(props, + Authentication.Property.USERNAME.getName()); + String password = getRequiredStringProp(props, + Authentication.Property.PASSWORD.getName()); + return new Authentication.BasicAuthBuilder(username, password).build(); + case BEARER: + String token = getRequiredStringProp(props, + Authentication.Property.ACCESS_TOKEN.getName()); + return new Authentication.BearerAuthBuilder(token).build(); + case API_KEY: + String header = getRequiredStringProp(props, + Authentication.Property.HEADER.getName()); + String value = getRequiredStringProp(props, + Authentication.Property.VALUE.getName()); + return new Authentication.APIKeyAuthBuilder(header, value).build(); + case CLIENT_CREDENTIAL: + String clientId = getRequiredStringProp(props, + Authentication.Property.CLIENT_ID.getName()); + String clientSecret = getRequiredStringProp(props, + Authentication.Property.CLIENT_SECRET.getName()); + String tokenEndpoint = getRequiredStringProp(props, + Authentication.Property.TOKEN_ENDPOINT.getName()); + String scopes = getOptionalStringProp(props, + Authentication.Property.SCOPES.getName()); + return new Authentication.ClientCredentialAuthBuilder( + clientId, clientSecret, tokenEndpoint, scopes).build(); + case NONE: + return new Authentication.NoneAuthBuilder().build(); + default: + throw new ActionMgtClientException( + ERROR_CODE_INVALID_ENDPOINT_AUTH_PROPERTIES.getMessage(), + ERROR_CODE_INVALID_ENDPOINT_AUTH_PROPERTIES.getDescription(), + ERROR_CODE_INVALID_ENDPOINT_AUTH_PROPERTIES.getCode()); + } + } + + private static String getRequiredStringProp(Map props, String key) + throws ActionMgtClientException { + + if (props == null || !props.containsKey(key)) { + throw new ActionMgtClientException( + ERROR_CODE_INVALID_ENDPOINT_AUTH_PROPERTIES.getMessage(), + ERROR_CODE_INVALID_ENDPOINT_AUTH_PROPERTIES.getDescription(), + ERROR_CODE_INVALID_ENDPOINT_AUTH_PROPERTIES.getCode()); + } + String val = (String) props.get(key); + if (StringUtils.isEmpty(val)) { + throw new ActionMgtClientException( + ERROR_CODE_EMPTY_ENDPOINT_AUTH_PROPERTIES.getMessage(), + ERROR_CODE_EMPTY_ENDPOINT_AUTH_PROPERTIES.getDescription(), + ERROR_CODE_EMPTY_ENDPOINT_AUTH_PROPERTIES.getCode()); + } + return val; + } + + private static String getOptionalStringProp(Map props, String key) { + + if (props == null || !props.containsKey(key)) { + return null; + } + Object val = props.get(key); + return (val instanceof String) ? (String) val : null; + } + + // ------------------------------------------------------------------------- + // Private helpers — AccessConfig + // ------------------------------------------------------------------------- + + private static org.wso2.carbon.identity.flow.extensions.model.AccessConfig + toEngineAccessConfig(AccessConfig model) { + + if (model == null) { + return null; + } + List expose = + toEngineContextPaths(model.getExpose()); + List modify = + toEngineContextPaths(model.getModify()); + + return new org.wso2.carbon.identity.flow.extensions.model + .AccessConfig(expose, modify); + } + + private static List + toEngineContextPaths(List apiPaths) { + + if (apiPaths == null) { + return null; + } + return apiPaths.stream() + .map(cp -> new org.wso2.carbon.identity.flow.extensions.model + .ContextPath(cp.getPath(), Boolean.TRUE.equals(cp.getEncrypted()))) + .collect(Collectors.toList()); + } + + private static AccessConfig toApiAccessConfig( + org.wso2.carbon.identity.flow.extensions.model.AccessConfig engineConfig) { + + if (engineConfig == null) { + return null; + } + AccessConfig model = new AccessConfig(); + if (engineConfig.getExpose() != null) { + model.setExpose(engineConfig.getExpose().stream() + .map(cp -> new ContextPath().path(cp.getPath()).encrypted(cp.isEncrypted())) + .collect(Collectors.toList())); + } + if (engineConfig.getModify() != null) { + model.setModify(engineConfig.getModify().stream() + .map(cp -> new ContextPath().path(cp.getPath()).encrypted(cp.isEncrypted())) + .collect(Collectors.toList())); + } + return model; + } + + // ------------------------------------------------------------------------- + // Private helpers — Encryption + // ------------------------------------------------------------------------- + + private static org.wso2.carbon.identity.flow.extensions.model.Encryption + toEngineEncryption(Encryption model) { + + if (model == null) { + return null; + } + if (StringUtils.isBlank(model.getCertificate())) { + // Blank/null certificate in the update request signals explicit removal. + // Return Encryption with null certificate so buildActionDTO stores "" (String), + // which handleCertificateUpdate recognises as isExplicitRemoval. + return new org.wso2.carbon.identity.flow.extensions.model.Encryption(null); + } + // Pass the raw PEM string to the framework; the DTOModelResolver (InFlowExtensionActionDTOModelResolver) + // takes care of persisting it via CertificateManagementService and replacing with a UUID. + Certificate cert = new Certificate.Builder() + .certificateContent(model.getCertificate()) + .build(); + return new org.wso2.carbon.identity.flow.extensions.model.Encryption(cert); + } + + private static Encryption toApiEncryption( + org.wso2.carbon.identity.flow.extensions.model.Encryption engineEncryption) { + + // The certificate is resolved back to a Certificate object by the DTOModelResolver on GET. + // We intentionally do not echo the certificate content back in the response. + if (engineEncryption == null || engineEncryption.getCertificate() == null) { + return null; + } + // Return an Encryption object without the certificate content (treat as opaque). + return new Encryption(); + } +} diff --git a/components/org.wso2.carbon.identity.api.server.flow.management/org.wso2.carbon.identity.api.server.flow.management.v1/src/main/java/org/wso2/carbon/identity/api/server/flow/management/v1/utils/Utils.java b/components/org.wso2.carbon.identity.api.server.flow.management/org.wso2.carbon.identity.api.server.flow.management.v1/src/main/java/org/wso2/carbon/identity/api/server/flow/management/v1/utils/Utils.java index d46e09ddaa..0049e23858 100644 --- a/components/org.wso2.carbon.identity.api.server.flow.management/org.wso2.carbon.identity.api.server.flow.management.v1/src/main/java/org/wso2/carbon/identity/api/server/flow/management/v1/utils/Utils.java +++ b/components/org.wso2.carbon.identity.api.server.flow.management/org.wso2.carbon.identity.api.server.flow.management.v1/src/main/java/org/wso2/carbon/identity/api/server/flow/management/v1/utils/Utils.java @@ -27,6 +27,9 @@ import org.apache.commons.logging.LogFactory; import org.wso2.carbon.context.CarbonContext; import org.wso2.carbon.context.PrivilegedCarbonContext; +import org.wso2.carbon.identity.action.management.api.constant.ErrorMessage; +import org.wso2.carbon.identity.action.management.api.exception.ActionMgtClientException; +import org.wso2.carbon.identity.action.management.api.exception.ActionMgtException; import org.wso2.carbon.identity.api.server.common.error.APIError; import org.wso2.carbon.identity.api.server.common.error.ErrorDTO; import org.wso2.carbon.identity.api.server.flow.management.common.FlowMgtServiceHolder; @@ -157,6 +160,36 @@ public static APIError handleFlowMgtException(FlowMgtFrameworkException e, Objec return handleFlowMgtException(e); } + /** + * Handles {@link ActionMgtException} thrown when calling {@link + * org.wso2.carbon.identity.action.management.api.service.ActionManagementService} from the + * flow management layer and converts it into an {@link APIError}. + * + * @param e ActionMgtException object. + * @return APIError object. + */ + public static APIError handleActionMgtException(ActionMgtException e) { + + Response.Status status = Response.Status.INTERNAL_SERVER_ERROR; + if (e instanceof ActionMgtClientException) { + LOG.debug(e.getMessage(), e); + String rawCode = e.getErrorCode(); + if (ErrorMessage.ERROR_NO_ACTION_CONFIGURED_ON_GIVEN_ACTION_TYPE_AND_ID.getCode().equals(rawCode)) { + status = Response.Status.NOT_FOUND; + } else if (ErrorMessage.ERROR_ACTION_NAME_ALREADY_EXISTS.getCode().equals(rawCode)) { + status = Response.Status.CONFLICT; + } else { + status = Response.Status.BAD_REQUEST; + } + } else { + LOG.error(e.getMessage(), e); + } + String errorCode = e.getErrorCode(); + errorCode = (errorCode != null && errorCode.contains(ERROR_CODE_DELIMITER)) + ? errorCode : FlowEndpointConstants.FLOW_PREFIX + errorCode; + return handleException(status, errorCode, e.getMessage(), e.getDescription()); + } + /** * Returns a generic error object. * diff --git a/components/org.wso2.carbon.identity.api.server.flow.management/org.wso2.carbon.identity.api.server.flow.management.v1/src/main/resources/flow.yaml b/components/org.wso2.carbon.identity.api.server.flow.management/org.wso2.carbon.identity.api.server.flow.management.v1/src/main/resources/flow.yaml index b6d04c5742..6284c2e82d 100644 --- a/components/org.wso2.carbon.identity.api.server.flow.management/org.wso2.carbon.identity.api.server.flow.management.v1/src/main/resources/flow.yaml +++ b/components/org.wso2.carbon.identity.api.server.flow.management/org.wso2.carbon.identity.api.server.flow.management.v1/src/main/resources/flow.yaml @@ -206,6 +206,282 @@ paths: application/json: schema: $ref: '#/components/schemas/Error' + /flow/in-flow-extensions: + post: + tags: + - Flow Composer - Extensions + summary: Create In-Flow Extension + description: "Creates an in-flow extension and returns the details along with the unique ID.\n\nScope (Permission) required: ``internal_flow_mgt_update``\n\n" + operationId: createInFlowExtension + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/InFlowExtensionModel' + required: true + responses: + '201': + description: In-Flow Extension Created + content: + application/json: + schema: + $ref: '#/components/schemas/InFlowExtensionResponse' + '400': + description: Bad Request + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + '401': + description: Unauthorized + '403': + description: Forbidden + '500': + description: Server Error + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + get: + tags: + - Flow Composer - Extensions + summary: List In-Flow Extensions + description: "Returns a list of all configured in-flow extensions.\n\nScope (Permission) required: ``internal_flow_mgt_view``\n\n" + operationId: getInFlowExtensions + responses: + '200': + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/InFlowExtensionResponseList' + '401': + description: Unauthorized + '403': + description: Forbidden + '500': + description: Server Error + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + + /flow/in-flow-extensions/check-name: + post: + tags: + - Flow Composer - Extensions + summary: Check Extension Name Availability + description: "Checks whether the given in-flow extension name is available.\n\nScope (Permission) required: ``internal_flow_mgt_view``\n\n" + operationId: checkInFlowExtensionName + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/InFlowExtensionNameCheckRequest' + required: true + responses: + '200': + description: Name availability check result + content: + application/json: + schema: + $ref: '#/components/schemas/InFlowExtensionNameCheckResponse' + '400': + description: Bad Request + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + '401': + description: Unauthorized + '403': + description: Forbidden + '500': + description: Server Error + + /flow/in-flow-extensions/{extensionId}: + get: + tags: + - Flow Composer - Extensions + summary: Retrieve In-Flow Extension by ID + description: "Retrieves the in-flow extension by its ID.\n\nScope (Permission) required: ``internal_flow_mgt_view``\n\n" + operationId: getInFlowExtensionById + parameters: + - name: extensionId + in: path + description: Unique identifier of the extension. + required: true + schema: + type: string + responses: + '200': + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/InFlowExtensionResponse' + '401': + description: Unauthorized + '403': + description: Forbidden + '404': + description: Not Found + '500': + description: Server Error + patch: + tags: + - Flow Composer - Extensions + summary: Update In-Flow Extension + description: "Updates an existing in-flow extension.\n\nScope (Permission) required: ``internal_flow_mgt_update``\n\n" + operationId: updateInFlowExtension + parameters: + - name: extensionId + in: path + description: Unique identifier of the extension. + required: true + schema: + type: string + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/InFlowExtensionUpdateModel' + required: true + responses: + '200': + description: Extension Updated + content: + application/json: + schema: + $ref: '#/components/schemas/InFlowExtensionResponse' + '400': + description: Bad Request + '401': + description: Unauthorized + '403': + description: Forbidden + '404': + description: Not Found + '500': + description: Server Error + delete: + tags: + - Flow Composer - Extensions + summary: Delete In-Flow Extension + description: "Deletes an in-flow extension by its ID.\n\nScope (Permission) required: ``internal_flow_mgt_update``\n\n" + operationId: deleteInFlowExtension + parameters: + - name: extensionId + in: path + description: Unique identifier of the extension. + required: true + schema: + type: string + responses: + '204': + description: Extension Deleted + '400': + description: Bad Request + '401': + description: Unauthorized + '403': + description: Forbidden + '500': + description: Server Error + + /flow/in-flow-extension/context-tree: + get: + summary: Retrieve the controlled In-Flow Extension context tree + description: > + Returns the canonical context tree filtered by the deployment.toml whitelist + ([identity.in_flow_extension.context.{flow_type}]) for the given flow type. + When `flowType` is omitted the default tree is returned. Used by the Console UI + to render the In-Flow Extension access-config editor without offering paths + the deployment has switched off, and to drive per-flow-type policy flags such + as `redirectionEnabled` and `allowReadOnlyClaimsModification`. + operationId: getInFlowExtensionContextTree + tags: + - Flow Composer + parameters: + - in: query + name: flowType + required: false + schema: + type: string + enum: [REGISTRATION, PASSWORD_RECOVERY, INVITED_USER_REGISTRATION, ASK_PASSWORD] + description: Optional flow type. When omitted, the default tree is returned. + responses: + '200': + description: Successfully retrieved the context tree + content: + application/json: + schema: + $ref: '#/components/schemas/InFlowExtensionContextTreeResponse' + '400': + description: Invalid flow type specified + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + '401': + description: Unauthorized + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + '403': + description: Forbidden + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + + /flow/in-flow-extension/context-tree: + get: + summary: Retrieve the controlled In-Flow Extension context tree + description: > + Returns the canonical context tree filtered by the deployment.toml whitelist + ([identity.in_flow_extension.context.{flow_type}]) for the given flow type. + When `flowType` is omitted the default tree is returned. Used by the Console UI + to render the In-Flow Extension access-config editor without offering paths + the deployment has switched off, and to drive per-flow-type policy flags such + as `redirectionEnabled` and `allowReadOnlyClaimsModification`. + operationId: getInFlowExtensionContextTree + tags: + - Flow Composer + parameters: + - in: query + name: flowType + required: false + schema: + type: string + enum: [REGISTRATION, PASSWORD_RECOVERY, INVITED_USER_REGISTRATION, ASK_PASSWORD] + description: Optional flow type. When omitted, the default tree is returned. + responses: + '200': + description: Successfully retrieved the context tree + content: + application/json: + schema: + $ref: '#/components/schemas/InFlowExtensionContextTreeResponse' + '400': + description: Invalid flow type specified + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + '401': + description: Unauthorized + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + '403': + description: Forbidden + content: + application/json: + schema: + $ref: '#/components/schemas/Error' /flow/configs: get: @@ -568,6 +844,10 @@ components: type: array items: $ref: '#/components/schemas/ExecutorConnections' + inflowExtensionConnections: + type: array + items: + $ref: '#/components/schemas/InFlowExtensionConnectionInfo' workflowEnabled: type: boolean example: false @@ -586,6 +866,20 @@ components: type: string example: IdpName + InFlowExtensionConnectionInfo: + type: object + description: In-flow extension connection info for flow metadata + properties: + actionId: + type: string + description: The unique identifier of the in-flow extension action. + name: + type: string + description: The name of the in-flow extension. + iconUrl: + type: string + description: The URL of the icon associated with the in-flow extension. + AttributeMetadata: type: object description: Attribute metadata @@ -786,6 +1080,284 @@ components: type: number example: 200.22 + InFlowExtensionModel: + type: object + required: + - name + - endpoint + properties: + name: + type: string + description: Name of the extension. + example: Risk Assessment Extension + description: + type: string + description: Description of the extension. + example: This action invokes during flow execution to assess risk. + endpoint: + $ref: '#/components/schemas/Endpoint' + accessConfig: + $ref: '#/components/schemas/AccessConfig' + encryption: + $ref: '#/components/schemas/Encryption' + + InFlowExtensionUpdateModel: + type: object + properties: + name: + type: string + description: + type: string + version: + type: string + endpoint: + $ref: '#/components/schemas/EndpointUpdateModel' + accessConfig: + $ref: '#/components/schemas/AccessConfig' + encryption: + $ref: '#/components/schemas/Encryption' + + InFlowExtensionResponse: + type: object + properties: + id: + type: string + name: + type: string + description: + type: string + status: + type: string + enum: [ ACTIVE, INACTIVE ] + version: + type: string + createdAt: + type: string + updatedAt: + type: string + endpoint: + $ref: '#/components/schemas/EndpointResponse' + accessConfig: + $ref: '#/components/schemas/AccessConfig' + encryption: + $ref: '#/components/schemas/Encryption' + + InFlowExtensionBasicResponse: + type: object + properties: + id: + type: string + name: + type: string + description: + type: string + status: + type: string + enum: [ ACTIVE, INACTIVE ] + version: + type: string + createdAt: + type: string + updatedAt: + type: string + links: + type: array + items: + $ref: '#/components/schemas/Link' + + InFlowExtensionResponseList: + type: array + items: + $ref: '#/components/schemas/InFlowExtensionBasicResponse' + + InFlowExtensionNameCheckRequest: + type: object + required: + - name + properties: + name: + type: string + excludeId: + type: string + + InFlowExtensionNameCheckResponse: + type: object + properties: + available: + type: boolean + + Endpoint: + type: object + required: + - uri + - authentication + properties: + uri: + type: string + pattern: '^https?://.+' + authentication: + $ref: '#/components/schemas/AuthenticationType' + allowedHeaders: + type: array + items: + type: string + + EndpointUpdateModel: + type: object + properties: + uri: + type: string + pattern: '^https?://.+' + authentication: + $ref: '#/components/schemas/AuthenticationType' + allowedHeaders: + type: array + items: + type: string + + EndpointResponse: + type: object + properties: + uri: + type: string + authentication: + $ref: '#/components/schemas/AuthenticationTypeResponse' + allowedHeaders: + type: array + items: + type: string + + AuthenticationType: + type: object + required: + - type + properties: + type: + type: string + enum: [ NONE, BEARER, API_KEY, BASIC, CLIENT_CREDENTIAL ] + properties: + type: object + additionalProperties: true + + AuthenticationTypeResponse: + type: object + properties: + type: + type: string + enum: [ NONE, BEARER, API_KEY, BASIC, CLIENT_CREDENTIAL ] + + Link: + type: object + properties: + href: + type: string + method: + type: string + enum: [ GET ] + rel: + type: string + + AccessConfig: + type: object + properties: + expose: + type: array + items: + $ref: '#/components/schemas/ContextPath' + modify: + type: array + items: + $ref: '#/components/schemas/ContextPath' + + ContextPath: + type: object + required: + - path + properties: + path: + type: string + encrypted: + type: boolean + default: false + + Encryption: + type: object + properties: + certificate: + type: string + + InFlowExtensionContextTreeResponse: + type: object + description: > + Controlled In-Flow Extension context tree for a given flow type, plus per-flow-type + policy flags consumed by the Console UI. + properties: + flowType: + type: string + description: Echoed flow type. `null` when no flowType was supplied (default tree). + example: PASSWORD_RECOVERY + contextTree: + type: array + description: > + Tree of context fields available for the active flow type. Fields disabled at + the deployment.toml whitelist level are omitted entirely. + items: + $ref: '#/components/schemas/InFlowExtensionContextTreeNode' + redirectionEnabled: + type: boolean + description: Whether REDIRECT is advertised in `allowedOperations` for this flow type. + example: true + allowReadOnlyClaimsModification: + type: boolean + description: > + Whether the Console UI may permit MODIFY on read-only claims for this flow type. + Hardcoded enumerative mapping in the engine. + example: true + + InFlowExtensionContextTreeNode: + type: object + description: One node in the controlled In-Flow Extension context tree. + properties: + key: + type: string + example: userId + title: + type: string + example: User ID + path: + type: string + example: /user/userId + dataType: + type: string + example: String + nodeType: + type: string + description: Tree node type. + enum: [OBJECT, LEAF, MAP, COMPLEX_MAP] + example: LEAF + allowedOperations: + type: array + description: Operations the admin may configure on this node. + items: + type: string + enum: [EXPOSE, MODIFY] + readOnly: + type: boolean + example: false + replaceable: + type: boolean + example: false + dynamicEntryAllowed: + type: boolean + example: true + dynamicEntryType: + type: string + example: String + children: + type: array + items: + $ref: '#/components/schemas/InFlowExtensionContextTreeNode' + Error: type: object properties: diff --git a/pom.xml b/pom.xml index 1b4dbd190f..b96d40baab 100644 --- a/pom.xml +++ b/pom.xml @@ -646,6 +646,12 @@ ${carbon.identity.framework.version} provided + + org.wso2.carbon.identity.framework + org.wso2.carbon.identity.flow.extensions + ${carbon.identity.framework.version} + provided + org.wso2.carbon.identity.framework org.wso2.carbon.identity.flow.mgt @@ -1057,7 +1063,7 @@ 1.4 1.2.4 1.11.103 - 7.10.68 + 7.11.90 3.0.5 4.9.8.2 4.9.8