From 94e7c77b21dcb02095db06ed43ab1b635b99dfee Mon Sep 17 00:00:00 2001 From: sahandilshan Date: Thu, 3 Oct 2024 18:08:37 +0530 Subject: [PATCH] Add api support to try out loginglow AI feature --- .../ApplicationManagementConstants.java | 10 +- .../ApplicationManagementServiceHolder.java | 20 ++ ...ginFlowAIManagementOSGiServiceFactory.java | 55 ++++ .../management/v1/ApplicationsApi.java | 70 ++++++ .../management/v1/ApplicationsApiService.java | 12 +- .../v1/LoginFlowGenerateRequest.java | 163 ++++++++++++ .../v1/LoginFlowGenerateResponse.java | 98 ++++++++ .../v1/LoginFlowResultResponse.java | 121 +++++++++ .../v1/LoginFlowStatusResponse.java | 120 +++++++++ .../application/management/v1/StatusEnum.java | 60 +++++ .../v1/core/LoginFlowAIService.java | 235 ++++++++++++++++++ .../v1/impl/ApplicationsApiServiceImpl.java | 31 +++ .../cxf/applications-server-v1-cxf.xml | 7 + .../src/main/resources/applications.yaml | 169 +++++++++++++ 14 files changed, 1169 insertions(+), 2 deletions(-) create mode 100644 components/org.wso2.carbon.identity.api.server.application.management/org.wso2.carbon.identity.api.server.application.management.common/src/main/java/org/wso2/carbon/identity/api/server/application/management/common/factory/LoginFlowAIManagementOSGiServiceFactory.java create mode 100644 components/org.wso2.carbon.identity.api.server.application.management/org.wso2.carbon.identity.api.server.application.management.v1/src/gen/java/org/wso2/carbon/identity/api/server/application/management/v1/LoginFlowGenerateRequest.java create mode 100644 components/org.wso2.carbon.identity.api.server.application.management/org.wso2.carbon.identity.api.server.application.management.v1/src/gen/java/org/wso2/carbon/identity/api/server/application/management/v1/LoginFlowGenerateResponse.java create mode 100644 components/org.wso2.carbon.identity.api.server.application.management/org.wso2.carbon.identity.api.server.application.management.v1/src/gen/java/org/wso2/carbon/identity/api/server/application/management/v1/LoginFlowResultResponse.java create mode 100644 components/org.wso2.carbon.identity.api.server.application.management/org.wso2.carbon.identity.api.server.application.management.v1/src/gen/java/org/wso2/carbon/identity/api/server/application/management/v1/LoginFlowStatusResponse.java create mode 100644 components/org.wso2.carbon.identity.api.server.application.management/org.wso2.carbon.identity.api.server.application.management.v1/src/gen/java/org/wso2/carbon/identity/api/server/application/management/v1/StatusEnum.java create mode 100644 components/org.wso2.carbon.identity.api.server.application.management/org.wso2.carbon.identity.api.server.application.management.v1/src/main/java/org/wso2/carbon/identity/api/server/application/management/v1/core/LoginFlowAIService.java diff --git a/components/org.wso2.carbon.identity.api.server.application.management/org.wso2.carbon.identity.api.server.application.management.common/src/main/java/org/wso2/carbon/identity/api/server/application/management/common/ApplicationManagementConstants.java b/components/org.wso2.carbon.identity.api.server.application.management/org.wso2.carbon.identity.api.server.application.management.common/src/main/java/org/wso2/carbon/identity/api/server/application/management/common/ApplicationManagementConstants.java index a6e3c3a3d7..e2db4928d5 100644 --- a/components/org.wso2.carbon.identity.api.server.application.management/org.wso2.carbon.identity.api.server.application.management.common/src/main/java/org/wso2/carbon/identity/api/server/application/management/common/ApplicationManagementConstants.java +++ b/components/org.wso2.carbon.identity.api.server.application.management/org.wso2.carbon.identity.api.server.application.management.common/src/main/java/org/wso2/carbon/identity/api/server/application/management/common/ApplicationManagementConstants.java @@ -205,7 +205,15 @@ public enum ErrorMessage { ERROR_RETRIEVING_USER_BY_ID("65503", "Error occurred while retrieving user", "Error occurred while retrieving user by userid: %s."), ERROR_RETRIEVING_USERSTORE_MANAGER("65504", "Error retrieving userstore manager.", - "Error occurred while retrieving userstore manager."); + "Error occurred while retrieving userstore manager."), + + // Login Flow AI Service related error messages. + ERROR_CODE_ERROR_GETTING_LOGINFLOW_AI_RESULT_STATUS("65600", + "Error occurred while getting the Login Flow AI result status.", + "Error occurred while getting the Login Flow AI result status."), + ERROR_CODE_ERROR_GETTING_LOGINFLOW_AI_RESULT("65601", + "Error occurred while getting the Login Flow AI result.", + "Error occurred while getting the Login Flow AI result."); private final String code; private final String message; diff --git a/components/org.wso2.carbon.identity.api.server.application.management/org.wso2.carbon.identity.api.server.application.management.common/src/main/java/org/wso2/carbon/identity/api/server/application/management/common/ApplicationManagementServiceHolder.java b/components/org.wso2.carbon.identity.api.server.application.management/org.wso2.carbon.identity.api.server.application.management.common/src/main/java/org/wso2/carbon/identity/api/server/application/management/common/ApplicationManagementServiceHolder.java index a0fbc6486d..5abfbb4778 100644 --- a/components/org.wso2.carbon.identity.api.server.application.management/org.wso2.carbon.identity.api.server.application.management.common/src/main/java/org/wso2/carbon/identity/api/server/application/management/common/ApplicationManagementServiceHolder.java +++ b/components/org.wso2.carbon.identity.api.server.application.management/org.wso2.carbon.identity.api.server.application.management.common/src/main/java/org/wso2/carbon/identity/api/server/application/management/common/ApplicationManagementServiceHolder.java @@ -18,6 +18,7 @@ import org.wso2.carbon.identity.api.resource.mgt.APIResourceManager; import org.wso2.carbon.identity.application.mgt.ApplicationManagementService; import org.wso2.carbon.identity.application.mgt.AuthorizedAPIManagementService; +import org.wso2.carbon.identity.application.mgt.ai.LoginFlowAIManager; import org.wso2.carbon.identity.cors.mgt.core.CORSManagementService; import org.wso2.carbon.identity.oauth.OAuthAdminServiceImpl; import org.wso2.carbon.identity.oauth.config.OAuthServerConfiguration; @@ -43,6 +44,7 @@ public class ApplicationManagementServiceHolder { private static APIResourceManager apiResourceManager; private static AuthorizedAPIManagementService authorizedAPIManagementService; private static OrgApplicationManager orgApplicationManager; + private static LoginFlowAIManager loginFlowAIManagementService; public static ApplicationManagementService getApplicationManagementService() { @@ -194,4 +196,22 @@ public static void setOrgApplicationManager(OrgApplicationManager orgApplication ApplicationManagementServiceHolder.orgApplicationManager = orgApplicationManager; } + + /** + * Get LoginFlowAIManagementService. + * @return LoginFlowAIManagementService + */ + public static LoginFlowAIManager getLoginFlowAIManagementService() { + + return loginFlowAIManagementService; + } + + /** + * Set LoginFlowAIManagementService. + * @param loginFlowAIManagementService LoginFlowAIManager. + */ + public static void setLoginFlowAIManagementService(LoginFlowAIManager loginFlowAIManagementService) { + + ApplicationManagementServiceHolder.loginFlowAIManagementService = loginFlowAIManagementService; + } } diff --git a/components/org.wso2.carbon.identity.api.server.application.management/org.wso2.carbon.identity.api.server.application.management.common/src/main/java/org/wso2/carbon/identity/api/server/application/management/common/factory/LoginFlowAIManagementOSGiServiceFactory.java b/components/org.wso2.carbon.identity.api.server.application.management/org.wso2.carbon.identity.api.server.application.management.common/src/main/java/org/wso2/carbon/identity/api/server/application/management/common/factory/LoginFlowAIManagementOSGiServiceFactory.java new file mode 100644 index 0000000000..fea39b40a1 --- /dev/null +++ b/components/org.wso2.carbon.identity.api.server.application.management/org.wso2.carbon.identity.api.server.application.management.common/src/main/java/org/wso2/carbon/identity/api/server/application/management/common/factory/LoginFlowAIManagementOSGiServiceFactory.java @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2024, WSO2 LLC. (http://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.wso2.carbon.identity.api.server.application.management.common.factory; + +import org.springframework.beans.factory.config.AbstractFactoryBean; +import org.wso2.carbon.context.PrivilegedCarbonContext; +import org.wso2.carbon.identity.application.mgt.ai.LoginFlowAIManager; + +/** + * Factory Beans serves as a factory for creating other beans within the IOC container. This factory bean is used to + * instantiate the LoginFlowAIManager type of object inside the container. + */ +public class LoginFlowAIManagementOSGiServiceFactory extends AbstractFactoryBean { + + private LoginFlowAIManager loginFlowAIManager; + + @Override + public Class getObjectType() { + return Object.class; + } + + @Override + protected LoginFlowAIManager createInstance() throws Exception { + + if (this.loginFlowAIManager == null) { + LoginFlowAIManager loginFlowAIManagementOSGiServiceFactory = + (LoginFlowAIManager) PrivilegedCarbonContext.getThreadLocalCarbonContext() + .getOSGiService(LoginFlowAIManager.class, null); + + if (loginFlowAIManagementOSGiServiceFactory != null) { + this.loginFlowAIManager = loginFlowAIManagementOSGiServiceFactory; + } else { + throw new Exception("Unable to retrieve ApplicationManagementService service."); + } + } + return this.loginFlowAIManager; + } + +} diff --git a/components/org.wso2.carbon.identity.api.server.application.management/org.wso2.carbon.identity.api.server.application.management.v1/src/gen/java/org/wso2/carbon/identity/api/server/application/management/v1/ApplicationsApi.java b/components/org.wso2.carbon.identity.api.server.application.management/org.wso2.carbon.identity.api.server.application.management.v1/src/gen/java/org/wso2/carbon/identity/api/server/application/management/v1/ApplicationsApi.java index f0cd6db86e..513045deb0 100644 --- a/components/org.wso2.carbon.identity.api.server.application.management/org.wso2.carbon.identity.api.server.application.management.v1/src/gen/java/org/wso2/carbon/identity/api/server/application/management/v1/ApplicationsApi.java +++ b/components/org.wso2.carbon.identity.api.server.application.management/org.wso2.carbon.identity.api.server.application.management.v1/src/gen/java/org/wso2/carbon/identity/api/server/application/management/v1/ApplicationsApi.java @@ -44,6 +44,10 @@ import org.wso2.carbon.identity.api.server.application.management.v1.Error; import java.io.File; import org.wso2.carbon.identity.api.server.application.management.v1.InboundProtocolListItem; +import org.wso2.carbon.identity.api.server.application.management.v1.LoginFlowGenerateRequest; +import org.wso2.carbon.identity.api.server.application.management.v1.LoginFlowGenerateResponse; +import org.wso2.carbon.identity.api.server.application.management.v1.LoginFlowResultResponse; +import org.wso2.carbon.identity.api.server.application.management.v1.LoginFlowStatusResponse; import org.wso2.carbon.identity.api.server.application.management.v1.OIDCMetaData; import org.wso2.carbon.identity.api.server.application.management.v1.OpenIDConnectConfiguration; import org.wso2.carbon.identity.api.server.application.management.v1.PassiveStsConfiguration; @@ -410,6 +414,30 @@ public Response exportApplicationAsFile(@ApiParam(value = "ID of the application return delegate.exportApplicationAsFile(applicationId, exportSecrets, accept ); } + @Valid + @POST + @Path("/loginflow/generate") + @Consumes({ "application/json" }) + @Produces({ "application/json" }) + @ApiOperation(value = "Initiate login flow generation", notes = "This API provides the capability to initiate the generation of a login flow.
Permission required: * /permission/admin/manage/identity/applicationmgt/update
Scope required: * internal_application_mgt_update ", response = LoginFlowGenerateResponse.class, authorizations = { + @Authorization(value = "BasicAuth"), + @Authorization(value = "OAuth2", scopes = { + + }) + }, tags={ "LoginFlow", }) + @ApiResponses(value = { + @ApiResponse(code = 202, message = "Accepted", response = LoginFlowGenerateResponse.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 = 404, message = "Not Found", response = Error.class), + @ApiResponse(code = 500, message = "Server Error", response = Error.class) + }) + public Response generateLoginFlow(@ApiParam(value = "" ,required=true) @Valid LoginFlowGenerateRequest loginFlowGenerateRequest) { + + return delegate.generateLoginFlow(loginFlowGenerateRequest ); + } + @Valid @GET @Path("/meta/adaptive-auth-templates") @@ -723,6 +751,48 @@ public Response getInboundSAMLConfiguration(@ApiParam(value = "ID of the applica return delegate.getInboundSAMLConfiguration(applicationId ); } + @Valid + @GET + @Path("/loginflow/result/{operation_id}") + + @Produces({ "application/json" }) + @ApiOperation(value = "Get the final login flow result", notes = "", response = LoginFlowResultResponse.class, authorizations = { + @Authorization(value = "BasicAuth"), + @Authorization(value = "OAuth2", scopes = { + + }) + }, tags={ "LoginFlow", }) + @ApiResponses(value = { + @ApiResponse(code = 200, message = "OK", response = LoginFlowResultResponse.class), + @ApiResponse(code = 400, message = "Bad Request", response = Error.class), + @ApiResponse(code = 404, message = "Not Found", response = Error.class) + }) + public Response getLoginFlowResult(@ApiParam(value = "",required=true) @PathParam("operation_id") String operationId) { + + return delegate.getLoginFlowResult(operationId ); + } + + @Valid + @GET + @Path("/loginflow/status/{operation_id}") + + @Produces({ "application/json" }) + @ApiOperation(value = "Get the status of the login flow generation process", notes = "", response = LoginFlowStatusResponse.class, authorizations = { + @Authorization(value = "BasicAuth"), + @Authorization(value = "OAuth2", scopes = { + + }) + }, tags={ "LoginFlow", }) + @ApiResponses(value = { + @ApiResponse(code = 200, message = "OK", response = LoginFlowStatusResponse.class), + @ApiResponse(code = 400, message = "Bad Request", response = Error.class), + @ApiResponse(code = 404, message = "Not Found", response = Error.class) + }) + public Response getLoginFlowStatus(@ApiParam(value = "",required=true) @PathParam("operation_id") String operationId) { + + return delegate.getLoginFlowStatus(operationId ); + } + @Valid @GET @Path("/meta/inbound-protocols/oidc") diff --git a/components/org.wso2.carbon.identity.api.server.application.management/org.wso2.carbon.identity.api.server.application.management.v1/src/gen/java/org/wso2/carbon/identity/api/server/application/management/v1/ApplicationsApiService.java b/components/org.wso2.carbon.identity.api.server.application.management/org.wso2.carbon.identity.api.server.application.management.v1/src/gen/java/org/wso2/carbon/identity/api/server/application/management/v1/ApplicationsApiService.java index c90527e09b..c9935d33be 100644 --- a/components/org.wso2.carbon.identity.api.server.application.management/org.wso2.carbon.identity.api.server.application.management.v1/src/gen/java/org/wso2/carbon/identity/api/server/application/management/v1/ApplicationsApiService.java +++ b/components/org.wso2.carbon.identity.api.server.application.management/org.wso2.carbon.identity.api.server.application.management.v1/src/gen/java/org/wso2/carbon/identity/api/server/application/management/v1/ApplicationsApiService.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, WSO2 LLC. (http://www.wso2.com). + * Copyright (c) 2024, WSO2 LLC. (http://www.wso2.com). * * WSO2 LLC. licenses this file to you under the Apache License, * Version 2.0 (the "License"); you may not use this file except @@ -41,6 +41,10 @@ import org.wso2.carbon.identity.api.server.application.management.v1.Error; import java.io.File; import org.wso2.carbon.identity.api.server.application.management.v1.InboundProtocolListItem; +import org.wso2.carbon.identity.api.server.application.management.v1.LoginFlowGenerateRequest; +import org.wso2.carbon.identity.api.server.application.management.v1.LoginFlowGenerateResponse; +import org.wso2.carbon.identity.api.server.application.management.v1.LoginFlowResultResponse; +import org.wso2.carbon.identity.api.server.application.management.v1.LoginFlowStatusResponse; import org.wso2.carbon.identity.api.server.application.management.v1.OIDCMetaData; import org.wso2.carbon.identity.api.server.application.management.v1.OpenIDConnectConfiguration; import org.wso2.carbon.identity.api.server.application.management.v1.PassiveStsConfiguration; @@ -84,6 +88,8 @@ public interface ApplicationsApiService { public Response exportApplicationAsFile(String applicationId, Boolean exportSecrets, String accept); + public Response generateLoginFlow(LoginFlowGenerateRequest loginFlowGenerateRequest); + public Response getAdaptiveAuthTemplates(); public Response getAllApplicationTemplates(Integer limit, Integer offset, SearchContext searchContext); @@ -110,6 +116,10 @@ public interface ApplicationsApiService { public Response getInboundSAMLConfiguration(String applicationId); + public Response getLoginFlowResult(String operationId); + + public Response getLoginFlowStatus(String operationId); + public Response getOIDCMetadata(); public Response getPassiveStsConfiguration(String applicationId); diff --git a/components/org.wso2.carbon.identity.api.server.application.management/org.wso2.carbon.identity.api.server.application.management.v1/src/gen/java/org/wso2/carbon/identity/api/server/application/management/v1/LoginFlowGenerateRequest.java b/components/org.wso2.carbon.identity.api.server.application.management/org.wso2.carbon.identity.api.server.application.management.v1/src/gen/java/org/wso2/carbon/identity/api/server/application/management/v1/LoginFlowGenerateRequest.java new file mode 100644 index 0000000000..c46181d19c --- /dev/null +++ b/components/org.wso2.carbon.identity.api.server.application.management/org.wso2.carbon.identity.api.server.application.management.v1/src/gen/java/org/wso2/carbon/identity/api/server/application/management/v1/LoginFlowGenerateRequest.java @@ -0,0 +1,163 @@ +/* + * Copyright (c) 2024, WSO2 LLC. (http://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.wso2.carbon.identity.api.server.application.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.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 LoginFlowGenerateRequest { + + private Map>> availableAuthenticators = null; + + private List> userClaims = null; + + private String userQuery; + + /** + **/ + public LoginFlowGenerateRequest availableAuthenticators(Map>> availableAuthenticators) { + + this.availableAuthenticators = availableAuthenticators; + return this; + } + + @ApiModelProperty(value = "") + @JsonProperty("available_authenticators") + @Valid + public Map>> getAvailableAuthenticators() { + return availableAuthenticators; + } + public void setAvailableAuthenticators(Map>> availableAuthenticators) { + this.availableAuthenticators = availableAuthenticators; + } + + + public LoginFlowGenerateRequest putAvailableAuthenticatorsItem(String key, List> availableAuthenticatorsItem) { + if (this.availableAuthenticators == null) { + this.availableAuthenticators = new HashMap<>(); + } + this.availableAuthenticators.put(key, availableAuthenticatorsItem); + return this; + } + + /** + **/ + public LoginFlowGenerateRequest userClaims(List> userClaims) { + + this.userClaims = userClaims; + return this; + } + + @ApiModelProperty(value = "") + @JsonProperty("user_claims") + @Valid + public List> getUserClaims() { + return userClaims; + } + public void setUserClaims(List> userClaims) { + this.userClaims = userClaims; + } + + public LoginFlowGenerateRequest addUserClaimsItem(Map userClaimsItem) { + if (this.userClaims == null) { + this.userClaims = new ArrayList<>(); + } + this.userClaims.add(userClaimsItem); + return this; + } + + /** + **/ + public LoginFlowGenerateRequest userQuery(String userQuery) { + + this.userQuery = userQuery; + return this; + } + + @ApiModelProperty(value = "") + @JsonProperty("user_query") + @Valid + public String getUserQuery() { + return userQuery; + } + public void setUserQuery(String userQuery) { + this.userQuery = userQuery; + } + + + + @Override + public boolean equals(java.lang.Object o) { + + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + LoginFlowGenerateRequest loginFlowGenerateRequest = (LoginFlowGenerateRequest) o; + return Objects.equals(this.availableAuthenticators, loginFlowGenerateRequest.availableAuthenticators) && + Objects.equals(this.userClaims, loginFlowGenerateRequest.userClaims) && + Objects.equals(this.userQuery, loginFlowGenerateRequest.userQuery); + } + + @Override + public int hashCode() { + return Objects.hash(availableAuthenticators, userClaims, userQuery); + } + + @Override + public String toString() { + + StringBuilder sb = new StringBuilder(); + sb.append("class LoginFlowGenerateRequest {\n"); + + sb.append(" availableAuthenticators: ").append(toIndentedString(availableAuthenticators)).append("\n"); + sb.append(" userClaims: ").append(toIndentedString(userClaims)).append("\n"); + sb.append(" userQuery: ").append(toIndentedString(userQuery)).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.application.management/org.wso2.carbon.identity.api.server.application.management.v1/src/gen/java/org/wso2/carbon/identity/api/server/application/management/v1/LoginFlowGenerateResponse.java b/components/org.wso2.carbon.identity.api.server.application.management/org.wso2.carbon.identity.api.server.application.management.v1/src/gen/java/org/wso2/carbon/identity/api/server/application/management/v1/LoginFlowGenerateResponse.java new file mode 100644 index 0000000000..ef6d0f8420 --- /dev/null +++ b/components/org.wso2.carbon.identity.api.server.application.management/org.wso2.carbon.identity.api.server.application.management.v1/src/gen/java/org/wso2/carbon/identity/api/server/application/management/v1/LoginFlowGenerateResponse.java @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2024, WSO2 LLC. (http://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.wso2.carbon.identity.api.server.application.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 LoginFlowGenerateResponse { + + private String operationId; + + /** + **/ + public LoginFlowGenerateResponse operationId(String operationId) { + + this.operationId = operationId; + return this; + } + + @ApiModelProperty(value = "") + @JsonProperty("operation_id") + @Valid + public String getOperationId() { + return operationId; + } + public void setOperationId(String operationId) { + this.operationId = operationId; + } + + + + @Override + public boolean equals(java.lang.Object o) { + + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + LoginFlowGenerateResponse loginFlowGenerateResponse = (LoginFlowGenerateResponse) o; + return Objects.equals(this.operationId, loginFlowGenerateResponse.operationId); + } + + @Override + public int hashCode() { + return Objects.hash(operationId); + } + + @Override + public String toString() { + + StringBuilder sb = new StringBuilder(); + sb.append("class LoginFlowGenerateResponse {\n"); + + sb.append(" operationId: ").append(toIndentedString(operationId)).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.application.management/org.wso2.carbon.identity.api.server.application.management.v1/src/gen/java/org/wso2/carbon/identity/api/server/application/management/v1/LoginFlowResultResponse.java b/components/org.wso2.carbon.identity.api.server.application.management/org.wso2.carbon.identity.api.server.application.management.v1/src/gen/java/org/wso2/carbon/identity/api/server/application/management/v1/LoginFlowResultResponse.java new file mode 100644 index 0000000000..54141a5917 --- /dev/null +++ b/components/org.wso2.carbon.identity.api.server.application.management/org.wso2.carbon.identity.api.server.application.management.v1/src/gen/java/org/wso2/carbon/identity/api/server/application/management/v1/LoginFlowResultResponse.java @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2024, WSO2 LLC. (http://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.wso2.carbon.identity.api.server.application.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.application.management.v1.StatusEnum; +import javax.validation.constraints.*; + + +import io.swagger.annotations.*; +import java.util.Objects; +import javax.validation.Valid; +import javax.xml.bind.annotation.*; + +public class LoginFlowResultResponse { + + private StatusEnum status; + private Object data; + + /** + **/ + public LoginFlowResultResponse 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; + } + + /** + * The payload of the response, which varies based on the operation status. - For IN_PROGRESS status, an empty JSON object is returned. - For COMPLETED status, the authentication sequence is returned. - For FAILED status, an error message is returned. + **/ + public LoginFlowResultResponse data(Object data) { + + this.data = data; + return this; + } + + @ApiModelProperty(value = "The payload of the response, which varies based on the operation status. - For IN_PROGRESS status, an empty JSON object is returned. - For COMPLETED status, the authentication sequence is returned. - For FAILED status, an error message is returned. ") + @JsonProperty("data") + @Valid + public Object getData() { + return data; + } + public void setData(Object data) { + this.data = data; + } + + + + @Override + public boolean equals(java.lang.Object o) { + + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + LoginFlowResultResponse loginFlowResultResponse = (LoginFlowResultResponse) o; + return Objects.equals(this.status, loginFlowResultResponse.status) && + Objects.equals(this.data, loginFlowResultResponse.data); + } + + @Override + public int hashCode() { + return Objects.hash(status, data); + } + + @Override + public String toString() { + + StringBuilder sb = new StringBuilder(); + sb.append("class LoginFlowResultResponse {\n"); + + sb.append(" status: ").append(toIndentedString(status)).append("\n"); + sb.append(" data: ").append(toIndentedString(data)).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.application.management/org.wso2.carbon.identity.api.server.application.management.v1/src/gen/java/org/wso2/carbon/identity/api/server/application/management/v1/LoginFlowStatusResponse.java b/components/org.wso2.carbon.identity.api.server.application.management/org.wso2.carbon.identity.api.server.application.management.v1/src/gen/java/org/wso2/carbon/identity/api/server/application/management/v1/LoginFlowStatusResponse.java new file mode 100644 index 0000000000..12f0531bee --- /dev/null +++ b/components/org.wso2.carbon.identity.api.server.application.management/org.wso2.carbon.identity.api.server.application.management.v1/src/gen/java/org/wso2/carbon/identity/api/server/application/management/v1/LoginFlowStatusResponse.java @@ -0,0 +1,120 @@ +/* + * Copyright (c) 2024, WSO2 LLC. (http://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.wso2.carbon.identity.api.server.application.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 LoginFlowStatusResponse { + + private String operationId; + private Object status; + + /** + **/ + public LoginFlowStatusResponse operationId(String operationId) { + + this.operationId = operationId; + return this; + } + + @ApiModelProperty(value = "") + @JsonProperty("operation_id") + @Valid + public String getOperationId() { + return operationId; + } + public void setOperationId(String operationId) { + this.operationId = operationId; + } + + /** + * A generic object representing the status + **/ + public LoginFlowStatusResponse status(Object status) { + + this.status = status; + return this; + } + + @ApiModelProperty(value = "A generic object representing the status") + @JsonProperty("status") + @Valid + public Object getStatus() { + return status; + } + public void setStatus(Object status) { + this.status = status; + } + + + + @Override + public boolean equals(java.lang.Object o) { + + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + LoginFlowStatusResponse loginFlowStatusResponse = (LoginFlowStatusResponse) o; + return Objects.equals(this.operationId, loginFlowStatusResponse.operationId) && + Objects.equals(this.status, loginFlowStatusResponse.status); + } + + @Override + public int hashCode() { + return Objects.hash(operationId, status); + } + + @Override + public String toString() { + + StringBuilder sb = new StringBuilder(); + sb.append("class LoginFlowStatusResponse {\n"); + + sb.append(" operationId: ").append(toIndentedString(operationId)).append("\n"); + sb.append(" status: ").append(toIndentedString(status)).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.application.management/org.wso2.carbon.identity.api.server.application.management.v1/src/gen/java/org/wso2/carbon/identity/api/server/application/management/v1/StatusEnum.java b/components/org.wso2.carbon.identity.api.server.application.management/org.wso2.carbon.identity.api.server.application.management.v1/src/gen/java/org/wso2/carbon/identity/api/server/application/management/v1/StatusEnum.java new file mode 100644 index 0000000000..2a4793959e --- /dev/null +++ b/components/org.wso2.carbon.identity.api.server.application.management/org.wso2.carbon.identity.api.server.application.management.v1/src/gen/java/org/wso2/carbon/identity/api/server/application/management/v1/StatusEnum.java @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2024, WSO2 LLC. (http://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.wso2.carbon.identity.api.server.application.management.v1; + +import javax.validation.constraints.*; + +import javax.xml.bind.annotation.XmlType; +import javax.xml.bind.annotation.XmlEnum; +import javax.xml.bind.annotation.XmlEnumValue; + +@XmlType(name="") +@XmlEnum(String.class) +public enum StatusEnum { + + @XmlEnumValue("IN_PROGRESS") IN_PROGRESS(String.valueOf("IN_PROGRESS")), @XmlEnumValue("COMPLETED") COMPLETED(String.valueOf("COMPLETED")), @XmlEnumValue("FAILED") FAILED(String.valueOf("FAILED")); + + + 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 + "'"); + } +} + + + diff --git a/components/org.wso2.carbon.identity.api.server.application.management/org.wso2.carbon.identity.api.server.application.management.v1/src/main/java/org/wso2/carbon/identity/api/server/application/management/v1/core/LoginFlowAIService.java b/components/org.wso2.carbon.identity.api.server.application.management/org.wso2.carbon.identity.api.server.application.management.v1/src/main/java/org/wso2/carbon/identity/api/server/application/management/v1/core/LoginFlowAIService.java new file mode 100644 index 0000000000..0740708963 --- /dev/null +++ b/components/org.wso2.carbon.identity.api.server.application.management/org.wso2.carbon.identity.api.server.application.management.v1/src/main/java/org/wso2/carbon/identity/api/server/application/management/v1/core/LoginFlowAIService.java @@ -0,0 +1,235 @@ +/* + * Copyright (c) 2024, WSO2 LLC. (http://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.wso2.carbon.identity.api.server.application.management.v1.core; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.json.JSONArray; +import org.json.JSONObject; +import org.wso2.carbon.identity.api.server.application.management.common.ApplicationManagementServiceHolder; +import org.wso2.carbon.identity.api.server.application.management.v1.LoginFlowGenerateRequest; +import org.wso2.carbon.identity.api.server.application.management.v1.LoginFlowGenerateResponse; +import org.wso2.carbon.identity.api.server.application.management.v1.LoginFlowResultResponse; +import org.wso2.carbon.identity.api.server.application.management.v1.LoginFlowStatusResponse; +import org.wso2.carbon.identity.api.server.application.management.v1.StatusEnum; +import org.wso2.carbon.identity.api.server.common.error.APIError; +import org.wso2.carbon.identity.api.server.common.error.ErrorResponse; +import org.wso2.carbon.identity.application.mgt.ai.LoginFlowAIClientException; +import org.wso2.carbon.identity.application.mgt.ai.LoginFlowAIServerException; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.ws.rs.core.Response; + +import static org.wso2.carbon.identity.api.server.application.management.common.ApplicationManagementConstants.ErrorMessage.ERROR_CODE_ERROR_GETTING_LOGINFLOW_AI_RESULT; +import static org.wso2.carbon.identity.api.server.application.management.common.ApplicationManagementConstants.ErrorMessage.ERROR_CODE_ERROR_GETTING_LOGINFLOW_AI_RESULT_STATUS; + +/** + * Service class for login flow AI related operations. + */ +public class LoginFlowAIService { + + private static final Log log = LogFactory.getLog(LoginFlowAIService.class); + + /** + * Generate authentication sequence. + * + * @param loginFlowGenerateRequest LoginFlowGenerateRequest. + * @return LoginFlowGenerateResponse. + */ + public LoginFlowGenerateResponse generateAuthenticationSequence(LoginFlowGenerateRequest loginFlowGenerateRequest) { + + try { + List> userClaims = loginFlowGenerateRequest.getUserClaims(); + JSONArray userClaimsJsonArray = new JSONArray(); + for (Map userClaim : userClaims) { + userClaimsJsonArray.put(new JSONObject() + .put("claimURI", userClaim.get("claimURI")) + .put("description", userClaim.get("description"))); + } + + JSONObject availableAuthenticators = new JSONObject(); + Map>> authenticators = loginFlowGenerateRequest + .getAvailableAuthenticators(); + for (Map.Entry>> entry : authenticators.entrySet()) { + String authenticatorType = entry.getKey(); + List> authenticatorList = entry.getValue(); + + JSONArray authenticatorsJsonArray = new JSONArray(); + for (Map authenticator : authenticatorList) { + authenticatorsJsonArray.put(new JSONObject() + .put("name", authenticator.get("name")) + .put("idp", authenticator.get("idp")) + .put("description", authenticator.get("description"))); + } + availableAuthenticators.put(authenticatorType, authenticatorsJsonArray); + } + + String operationId = ApplicationManagementServiceHolder.getLoginFlowAIManagementService() + .generateAuthenticationSequence(loginFlowGenerateRequest.getUserQuery(), userClaimsJsonArray, + availableAuthenticators); + LoginFlowGenerateResponse response = new LoginFlowGenerateResponse(); + response.setOperationId(operationId); + return response; + } catch (LoginFlowAIServerException e) { + throw handleServerException(e); + } catch (LoginFlowAIClientException e) { + throw handleClientException(e); + } + } + + /** + * Get login flow AI generation result. + * + * @param operationId Operation ID of the login flow AI generation. + * @return LoginFlowResultResponse. + */ + public LoginFlowResultResponse getLoginFlowAIGenerationResult(String operationId) { + + try { + Object generationResult = ApplicationManagementServiceHolder.getLoginFlowAIManagementService() + .getAuthenticationSequenceGenerationResult(operationId); + LoginFlowResultResponse response = new LoginFlowResultResponse(); + Map generationResultMap = (Map) generationResult; + response.setStatus(getStatusFromResult(generationResultMap)); + if (!((Map) generationResult).containsKey("data")) { + throw new LoginFlowAIServerException(ERROR_CODE_ERROR_GETTING_LOGINFLOW_AI_RESULT_STATUS.getMessage(), + ERROR_CODE_ERROR_GETTING_LOGINFLOW_AI_RESULT_STATUS.getCode()); + } + Map dataMap = (Map) generationResultMap.get("data"); + response.setData(dataMap); + return response; + } catch (LoginFlowAIServerException e) { + throw handleServerException(e); + } catch (LoginFlowAIClientException e) { + throw handleClientException(e); + } + } + + /** + * Get login flow AI generation status. + * + * @param operationId Operation ID of the login flow AI generation. + * @return LoginFlowStatusResponse. + */ + public LoginFlowStatusResponse getLoginFlowAIStatus(String operationId) { + + try { + Object generationStatus = ApplicationManagementServiceHolder.getLoginFlowAIManagementService() + .getAuthenticationSequenceGenerationStatus(operationId); + LoginFlowStatusResponse response = new LoginFlowStatusResponse(); + response.setOperationId(operationId); + + response.status(convertObjectToMap(generationStatus)); + return response; + } catch (LoginFlowAIServerException e) { + throw handleServerException(e); + } catch (LoginFlowAIClientException e) { + throw handleClientException(e); + } + } + + private StatusEnum getStatusFromResult(Map resultMap) + throws LoginFlowAIServerException { + + if (resultMap.containsKey("status")) { + String status = (String) resultMap.get("status"); + if ("IN_PROGRESS".equals(status)) { + return StatusEnum.IN_PROGRESS; + } else if ("COMPLETED".equals(status)) { + return StatusEnum.COMPLETED; + } else if ("FAILED".equals(status)) { + return StatusEnum.FAILED; + } + } + throw new LoginFlowAIServerException(ERROR_CODE_ERROR_GETTING_LOGINFLOW_AI_RESULT.getMessage(), + ERROR_CODE_ERROR_GETTING_LOGINFLOW_AI_RESULT.getCode()); + } + + private APIError handleClientException(LoginFlowAIClientException error) { + + ErrorResponse.Builder errorResponseBuilder = new ErrorResponse.Builder() + .withCode(error.getErrorCode()) + .withMessage(error.getMessage()); + if (error.getLoginFlowAIResponse() != null) { + Response.Status status = Response.Status.fromStatusCode(error.getLoginFlowAIResponse().getStatusCode()); + errorResponseBuilder.withDescription(error.getLoginFlowAIResponse().getResponseBody()); + return new APIError(status, errorResponseBuilder.build()); + } + return new APIError(Response.Status.BAD_REQUEST, errorResponseBuilder.build()); + } + + private APIError handleServerException(LoginFlowAIServerException error) { + + ErrorResponse.Builder errorResponseBuilder = new ErrorResponse.Builder() + .withCode(error.getErrorCode()) + .withMessage(error.getMessage()); + if (error.getBrandingAIResponse() != null) { + Response.Status status = Response.Status.fromStatusCode(error.getBrandingAIResponse().getStatusCode()); + errorResponseBuilder.withDescription(error.getBrandingAIResponse().getResponseBody()); + return new APIError(status, errorResponseBuilder.build()); + } + return new APIError(Response.Status.INTERNAL_SERVER_ERROR, errorResponseBuilder.build()); + } + + private static Map convertObjectToMap(Object object) { + + if (object instanceof Map) { + Map map = new HashMap<>(); + for (Map.Entry entry : ((Map) object).entrySet()) { + String key = entry.getKey(); + Object value = entry.getValue(); + + if (value == null) { + map.put(key, ""); + } else if (value instanceof Map) { + map.put(key, convertObjectToMap(value)); + } else if (value instanceof List) { + map.put(key, convertListToArray((List) value)); + } else { + map.put(key, value); + } + } + return map; + } + log.warn("Object is not an instance of Map. Returning an empty map."); + return new HashMap<>(); + } + + private static Object[] convertListToArray(List list) { + + Object[] array = new Object[list.size()]; + for (int i = 0; i < list.size(); i++) { + Object value = list.get(i); + if (value == null) { + array[i] = ""; + } else if (value instanceof Map) { + array[i] = convertObjectToMap(value); + } else if (value instanceof List) { + array[i] = convertListToArray((List) value); + } else { + array[i] = value; + } + } + return array; + } +} + diff --git a/components/org.wso2.carbon.identity.api.server.application.management/org.wso2.carbon.identity.api.server.application.management.v1/src/main/java/org/wso2/carbon/identity/api/server/application/management/v1/impl/ApplicationsApiServiceImpl.java b/components/org.wso2.carbon.identity.api.server.application.management/org.wso2.carbon.identity.api.server.application.management.v1/src/main/java/org/wso2/carbon/identity/api/server/application/management/v1/impl/ApplicationsApiServiceImpl.java index d6fef0ca9b..a6247edfd0 100644 --- a/components/org.wso2.carbon.identity.api.server.application.management/org.wso2.carbon.identity.api.server.application.management.v1/src/main/java/org/wso2/carbon/identity/api/server/application/management/v1/impl/ApplicationsApiServiceImpl.java +++ b/components/org.wso2.carbon.identity.api.server.application.management/org.wso2.carbon.identity.api.server.application.management.v1/src/main/java/org/wso2/carbon/identity/api/server/application/management/v1/impl/ApplicationsApiServiceImpl.java @@ -33,6 +33,10 @@ import org.wso2.carbon.identity.api.server.application.management.v1.AuthorizedAPIPatchModel; import org.wso2.carbon.identity.api.server.application.management.v1.CustomInboundProtocolConfiguration; import org.wso2.carbon.identity.api.server.application.management.v1.InboundProtocolListItem; +import org.wso2.carbon.identity.api.server.application.management.v1.LoginFlowGenerateRequest; +import org.wso2.carbon.identity.api.server.application.management.v1.LoginFlowGenerateResponse; +import org.wso2.carbon.identity.api.server.application.management.v1.LoginFlowResultResponse; +import org.wso2.carbon.identity.api.server.application.management.v1.LoginFlowStatusResponse; import org.wso2.carbon.identity.api.server.application.management.v1.OpenIDConnectConfiguration; import org.wso2.carbon.identity.api.server.application.management.v1.PassiveStsConfiguration; import org.wso2.carbon.identity.api.server.application.management.v1.ProvisioningConfiguration; @@ -40,6 +44,7 @@ import org.wso2.carbon.identity.api.server.application.management.v1.SAML2Configuration; import org.wso2.carbon.identity.api.server.application.management.v1.SAML2ServiceProvider; import org.wso2.carbon.identity.api.server.application.management.v1.WSTrustConfiguration; +import org.wso2.carbon.identity.api.server.application.management.v1.core.LoginFlowAIService; import org.wso2.carbon.identity.api.server.application.management.v1.core.ServerApplicationManagementService; import org.wso2.carbon.identity.api.server.application.management.v1.core.ServerApplicationMetadataService; import org.wso2.carbon.identity.api.server.application.management.v1.core.ServerApplicationSharingService; @@ -67,6 +72,9 @@ public class ApplicationsApiServiceImpl implements ApplicationsApiService { @Autowired private ServerApplicationSharingService applicationSharingService; + @Autowired + private LoginFlowAIService loginFlowAIService; + @Override public Response getAllApplications(Integer limit, Integer offset, String filter, String sortOrder, String sortBy, String requiredAttributes) { @@ -179,6 +187,21 @@ public Response getInboundSAMLConfiguration(String applicationId) { return Response.ok(samlSp).build(); } + @Override + public Response getLoginFlowResult(String operationId) { + + LoginFlowResultResponse loginFlowAIGenerationResult = loginFlowAIService.getLoginFlowAIGenerationResult( + operationId); + return Response.ok(loginFlowAIGenerationResult).build(); + } + + @Override + public Response getLoginFlowStatus(String operationId) { + + LoginFlowStatusResponse loginFlowAIStatus = loginFlowAIService.getLoginFlowAIStatus(operationId); + return Response.ok(loginFlowAIStatus).build(); + } + @Override public Response getPassiveStsConfiguration(String applicationId) { @@ -263,6 +286,14 @@ public Response exportApplicationAsFile(String applicationId, Boolean exportSecr .build(); } + @Override + public Response generateLoginFlow(LoginFlowGenerateRequest loginFlowGenerateRequest) { + + LoginFlowGenerateResponse loginFlowGenerateResponse = loginFlowAIService.generateAuthenticationSequence( + loginFlowGenerateRequest); + return Response.accepted(loginFlowGenerateResponse).build(); + } + @Override public Response importApplication(InputStream fileInputStream, Attachment fileDetail) { diff --git a/components/org.wso2.carbon.identity.api.server.application.management/org.wso2.carbon.identity.api.server.application.management.v1/src/main/resources/META-INF/cxf/applications-server-v1-cxf.xml b/components/org.wso2.carbon.identity.api.server.application.management/org.wso2.carbon.identity.api.server.application.management.v1/src/main/resources/META-INF/cxf/applications-server-v1-cxf.xml index 79bdb489c4..e2ae58f50f 100644 --- a/components/org.wso2.carbon.identity.api.server.application.management/org.wso2.carbon.identity.api.server.application.management.v1/src/main/resources/META-INF/cxf/applications-server-v1-cxf.xml +++ b/components/org.wso2.carbon.identity.api.server.application.management/org.wso2.carbon.identity.api.server.application.management.v1/src/main/resources/META-INF/cxf/applications-server-v1-cxf.xml @@ -19,6 +19,7 @@ xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"> + @@ -63,6 +64,10 @@ class="org.wso2.carbon.identity.api.server.application.management.common.ApplicationManagementServiceHolder"> + + + @@ -85,4 +90,6 @@ class="org.wso2.carbon.identity.api.server.application.management.common.factory.APIResourceMgtOSGiServiceFactory"/> + diff --git a/components/org.wso2.carbon.identity.api.server.application.management/org.wso2.carbon.identity.api.server.application.management.v1/src/main/resources/applications.yaml b/components/org.wso2.carbon.identity.api.server.application.management/org.wso2.carbon.identity.api.server.application.management.v1/src/main/resources/applications.yaml index 1667b034c3..a1983b5e62 100644 --- a/components/org.wso2.carbon.identity.api.server.application.management/org.wso2.carbon.identity.api.server.application.management.v1/src/main/resources/applications.yaml +++ b/components/org.wso2.carbon.identity.api.server.application.management/org.wso2.carbon.identity.api.server.application.management.v1/src/main/resources/applications.yaml @@ -2615,6 +2615,119 @@ paths: $ref: '#/components/schemas/Error' tags: - Organization Application Sharing + /applications/loginflow/generate: + post: + tags: + - LoginFlow + summary: Initiate login flow generation + description: > + This API provides the capability to initiate the generation of a login flow. +
+ Permission required: + * /permission/admin/manage/identity/applicationmgt/update +
+ Scope required: + * internal_application_mgt_update + operationId: generateLoginFlow + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/LoginFlowGenerateRequest' + responses: + '202': + description: Accepted + content: + application/json: + schema: + $ref: '#/components/schemas/LoginFlowGenerateResponse' + '400': + description: Bad Request + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + '401': + description: Unauthorized + '403': + description: Forbidden + '404': + description: Not Found + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + '500': + description: Server Error + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + + /applications/loginflow/status/{operation_id}: + get: + tags: + - LoginFlow + summary: Get the status of the login flow generation process + operationId: getLoginFlowStatus + parameters: + - name: operation_id + in: path + required: true + schema: + type: string + responses: + '200': + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/LoginFlowStatusResponse' + '400': + description: Bad Request + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + '404': + description: Not Found + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + + /applications/loginflow/result/{operation_id}: + get: + tags: + - LoginFlow + summary: Get the final login flow result + operationId: getLoginFlowResult + parameters: + - name: operation_id + in: path + required: true + schema: + type: string + responses: + '200': + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/LoginFlowResultResponse' + '400': + description: Bad Request + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + '404': + description: Not Found + content: + application/json: + schema: + $ref: '#/components/schemas/Error' components: parameters: @@ -4327,6 +4440,62 @@ components: ref: type: string example: '/t/wso2.com/api/server/v1/organizations/b4526d91-a8bf-43d2-8b14-c548cf73065b' + LoginFlowGenerateRequest: + type: object + properties: + available_authenticators: + type: object + additionalProperties: + type: array + items: + type: object + additionalProperties: true + user_claims: + type: array + items: + type: object + additionalProperties: true + user_query: + type: string + + LoginFlowGenerateResponse: + type: object + properties: + operation_id: + type: string + + StatusEnum: + type: string + enum: + - IN_PROGRESS + - COMPLETED + - FAILED + x-enum-varnames: + - IN_PROGRESS + - COMPLETED + - FAILED + + LoginFlowStatusResponse: + type: object + properties: + operation_id: + type: string + status: + type: object + description: A generic object representing the status + + LoginFlowResultResponse: + type: object + properties: + status: + $ref: '#/components/schemas/StatusEnum' + data: + type: object + description: | + The payload of the response, which varies based on the operation status. + - For IN_PROGRESS status, an empty JSON object is returned. + - For COMPLETED status, the authentication sequence is returned. + - For FAILED status, an error message is returned. Error: type: object