diff --git a/components/org.wso2.carbon.identity.api.server.configs/org.wso2.carbon.identity.api.server.configs.common/pom.xml b/components/org.wso2.carbon.identity.api.server.configs/org.wso2.carbon.identity.api.server.configs.common/pom.xml index 31d597d35e..2e8f64f61a 100644 --- a/components/org.wso2.carbon.identity.api.server.configs/org.wso2.carbon.identity.api.server.configs.common/pom.xml +++ b/components/org.wso2.carbon.identity.api.server.configs/org.wso2.carbon.identity.api.server.configs.common/pom.xml @@ -82,6 +82,11 @@ org.wso2.carbon.identity.scim2.common provided + + org.wso2.carbon.identity.framework + org.wso2.carbon.identity.fraud.detection.core + provided + diff --git a/components/org.wso2.carbon.identity.api.server.configs/org.wso2.carbon.identity.api.server.configs.common/src/main/java/org/wso2/carbon/identity/api/server/configs/common/ConfigsServiceHolder.java b/components/org.wso2.carbon.identity.api.server.configs/org.wso2.carbon.identity.api.server.configs.common/src/main/java/org/wso2/carbon/identity/api/server/configs/common/ConfigsServiceHolder.java index a54538e2d3..2ce812b016 100644 --- a/components/org.wso2.carbon.identity.api.server.configs/org.wso2.carbon.identity.api.server.configs.common/src/main/java/org/wso2/carbon/identity/api/server/configs/common/ConfigsServiceHolder.java +++ b/components/org.wso2.carbon.identity.api.server.configs/org.wso2.carbon.identity.api.server.configs.common/src/main/java/org/wso2/carbon/identity/api/server/configs/common/ConfigsServiceHolder.java @@ -23,6 +23,7 @@ import org.wso2.carbon.identity.application.mgt.ApplicationManagementService; import org.wso2.carbon.identity.claim.metadata.mgt.ClaimMetadataManagementService; import org.wso2.carbon.identity.cors.mgt.core.CORSManagementService; +import org.wso2.carbon.identity.fraud.detection.core.service.FraudDetectionConfigsService; import org.wso2.carbon.identity.oauth.dcr.DCRConfigurationMgtService; import org.wso2.carbon.identity.oauth2.impersonation.services.ImpersonationConfigMgtService; import org.wso2.carbon.identity.oauth2.token.handler.clientauth.jwt.core.JWTClientAuthenticatorMgtService; @@ -94,6 +95,13 @@ private static class ClaimMetaDataManagementServiceHolder { .getOSGiService(ClaimMetadataManagementService.class, null); } + private static class FraudDetectionConfigsServiceHolder { + + static final FraudDetectionConfigsService SERVICE = + (FraudDetectionConfigsService) PrivilegedCarbonContext.getThreadLocalCarbonContext() + .getOSGiService(FraudDetectionConfigsService.class, null); + } + /** * Get ApplicationManagementService osgi service. * @@ -183,4 +191,14 @@ public static ClaimMetadataManagementService getClaimMetadataManagementService() return ClaimMetaDataManagementServiceHolder.SERVICE; } + + /** + * Get FraudDetectionConfigsService osgi service. + * + * @return FraudDetectionConfigsService + */ + public static FraudDetectionConfigsService getFraudDetectionConfigsService() { + + return FraudDetectionConfigsServiceHolder.SERVICE; + } } diff --git a/components/org.wso2.carbon.identity.api.server.configs/org.wso2.carbon.identity.api.server.configs.common/src/main/java/org/wso2/carbon/identity/api/server/configs/common/Constants.java b/components/org.wso2.carbon.identity.api.server.configs/org.wso2.carbon.identity.api.server.configs.common/src/main/java/org/wso2/carbon/identity/api/server/configs/common/Constants.java index acc3fed2ee..d3c90f0431 100644 --- a/components/org.wso2.carbon.identity.api.server.configs/org.wso2.carbon.identity.api.server.configs.common/src/main/java/org/wso2/carbon/identity/api/server/configs/common/Constants.java +++ b/components/org.wso2.carbon.identity.api.server.configs/org.wso2.carbon.identity.api.server.configs.common/src/main/java/org/wso2/carbon/identity/api/server/configs/common/Constants.java @@ -208,7 +208,14 @@ public enum ErrorMessage { "Server encountered an error while deleting the Passive STS inbound auth configs."), ERROR_CODE_IMP_CONFIG_DELETE("65022", "Unable to delete Impersonation configuration.", - "Server encountered an error while deleting the Impersonation configuration of %s."); + "Server encountered an error while deleting the Impersonation configuration of %s."), + + ERROR_CODE_FRAUD_DETECTION_CONFIG_RETRIEVE("65023", + "Unable to retrieve Fraud Detection configuration.", + "Server encountered an error while retrieving the Fraud Detection configuration."), + ERROR_CODE_FRAUD_DETECTION_CONFIG_UPDATE("65024", + "Unable to update Fraud Detection configuration.", + "Server encountered an error while updating the Fraud Detection configuration."); private final String code; private final String message; diff --git a/components/org.wso2.carbon.identity.api.server.configs/org.wso2.carbon.identity.api.server.configs.v1/pom.xml b/components/org.wso2.carbon.identity.api.server.configs/org.wso2.carbon.identity.api.server.configs.v1/pom.xml index 18012c2d54..cc0c397206 100644 --- a/components/org.wso2.carbon.identity.api.server.configs/org.wso2.carbon.identity.api.server.configs.v1/pom.xml +++ b/components/org.wso2.carbon.identity.api.server.configs/org.wso2.carbon.identity.api.server.configs.v1/pom.xml @@ -185,6 +185,11 @@ org.wso2.carbon.logging.service provided + + org.wso2.carbon.identity.framework + org.wso2.carbon.identity.fraud.detection.core + provided + commons-beanutils commons-beanutils diff --git a/components/org.wso2.carbon.identity.api.server.configs/org.wso2.carbon.identity.api.server.configs.v1/src/gen/java/org/wso2/carbon/identity/api/server/configs/v1/ConfigsApi.java b/components/org.wso2.carbon.identity.api.server.configs/org.wso2.carbon.identity.api.server.configs.v1/src/gen/java/org/wso2/carbon/identity/api/server/configs/v1/ConfigsApi.java index 7454db23a5..2f093ace10 100644 --- a/components/org.wso2.carbon.identity.api.server.configs/org.wso2.carbon.identity.api.server.configs.v1/src/gen/java/org/wso2/carbon/identity/api/server/configs/v1/ConfigsApi.java +++ b/components/org.wso2.carbon.identity.api.server.configs/org.wso2.carbon.identity.api.server.configs.v1/src/gen/java/org/wso2/carbon/identity/api/server/configs/v1/ConfigsApi.java @@ -31,6 +31,7 @@ import org.wso2.carbon.identity.api.server.configs.v1.model.DCRConfig; import org.wso2.carbon.identity.api.server.configs.v1.model.DCRPatch; import org.wso2.carbon.identity.api.server.configs.v1.model.Error; +import org.wso2.carbon.identity.api.server.configs.v1.model.FraudDetectionConfig; import org.wso2.carbon.identity.api.server.configs.v1.model.ImpersonationConfiguration; import org.wso2.carbon.identity.api.server.configs.v1.model.ImpersonationPatch; import org.wso2.carbon.identity.api.server.configs.v1.model.InboundAuthPassiveSTSConfig; @@ -182,6 +183,30 @@ public Response getConfigs() { return delegate.getConfigs(); } + @Valid + @GET + @Path("/fraud-detection") + + @Produces({ "application/json" }) + @ApiOperation(value = "Get fraud detection configs.", notes = "Retrieve fraud detection related configurations of a tenant.", response = FraudDetectionConfig.class, authorizations = { + @Authorization(value = "BasicAuth"), + @Authorization(value = "OAuth2", scopes = { + + }) + }, tags={ "Fraud Detection", }) + @ApiResponses(value = { + @ApiResponse(code = 200, message = "Successfully retrieved.", response = FraudDetectionConfig.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 getFraudDetectionConfigs() { + + return delegate.getFraudDetectionConfigs(); + } + @Valid @GET @Path("/home-realm-identifiers") @@ -661,6 +686,30 @@ public Response deleteImpersonationConfiguration() { return delegate.deleteImpersonationConfiguration(); } + @Valid + @PUT + @Path("/fraud-detection") + @Consumes({ "application/json" }) + @Produces({ "application/json" }) + @ApiOperation(value = "Update fraud detection configs.", notes = "Update fraud detection related configuration of a tenant.", response = FraudDetectionConfig.class, authorizations = { + @Authorization(value = "BasicAuth"), + @Authorization(value = "OAuth2", scopes = { + + }) + }, tags={ "Fraud Detection", }) + @ApiResponses(value = { + @ApiResponse(code = 200, message = "Successfully updated.", response = FraudDetectionConfig.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 updateFraudDetectionConfigs(@ApiParam(value = "" ,required=true) @Valid FraudDetectionConfig fraudDetectionConfig) { + + return delegate.updateFraudDetectionConfigs(fraudDetectionConfig ); + } + @Valid @PUT @Path("/provisioning/inbound/scim") diff --git a/components/org.wso2.carbon.identity.api.server.configs/org.wso2.carbon.identity.api.server.configs.v1/src/gen/java/org/wso2/carbon/identity/api/server/configs/v1/ConfigsApiService.java b/components/org.wso2.carbon.identity.api.server.configs/org.wso2.carbon.identity.api.server.configs.v1/src/gen/java/org/wso2/carbon/identity/api/server/configs/v1/ConfigsApiService.java index e29d7a8fa1..f3a81d8cd5 100644 --- a/components/org.wso2.carbon.identity.api.server.configs/org.wso2.carbon.identity.api.server.configs.v1/src/gen/java/org/wso2/carbon/identity/api/server/configs/v1/ConfigsApiService.java +++ b/components/org.wso2.carbon.identity.api.server.configs/org.wso2.carbon.identity.api.server.configs.v1/src/gen/java/org/wso2/carbon/identity/api/server/configs/v1/ConfigsApiService.java @@ -57,6 +57,8 @@ public interface ConfigsApiService { public Response getConfigs(); + public Response getFraudDetectionConfigs(); + public Response getHomeRealmIdentifiers(); public Response getImpersonationConfiguration(); @@ -96,6 +98,8 @@ public interface ConfigsApiService { public Response deleteImpersonationConfiguration(); + public Response updateFraudDetectionConfigs(FraudDetectionConfig fraudDetectionConfig); + public Response updateInboundScimConfigs(ScimConfig scimConfig); public Response updatePassiveSTSInboundAuthConfig(InboundAuthPassiveSTSConfig inboundAuthPassiveSTSConfig); diff --git a/components/org.wso2.carbon.identity.api.server.configs/org.wso2.carbon.identity.api.server.configs.v1/src/gen/java/org/wso2/carbon/identity/api/server/configs/v1/model/EventConfig.java b/components/org.wso2.carbon.identity.api.server.configs/org.wso2.carbon.identity.api.server.configs.v1/src/gen/java/org/wso2/carbon/identity/api/server/configs/v1/model/EventConfig.java new file mode 100644 index 0000000000..092669956b --- /dev/null +++ b/components/org.wso2.carbon.identity.api.server.configs/org.wso2.carbon.identity.api.server.configs.v1/src/gen/java/org/wso2/carbon/identity/api/server/configs/v1/model/EventConfig.java @@ -0,0 +1,154 @@ +/* + * Copyright (c) 2023, 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.configs.v1.model; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import java.util.ArrayList; +import java.util.List; +import org.wso2.carbon.identity.api.server.configs.v1.model.EventProperty; +import javax.validation.constraints.*; + + +import io.swagger.annotations.*; +import java.util.Objects; +import javax.validation.Valid; +import javax.xml.bind.annotation.*; + +public class EventConfig { + + private String eventName; + private Boolean enabled; + private List properties = null; + + + /** + * Name of the event + **/ + public EventConfig eventName(String eventName) { + + this.eventName = eventName; + return this; + } + + @ApiModelProperty(example = "Event.User_registration", value = "Name of the event") + @JsonProperty("eventName") + @Valid + public String getEventName() { + return eventName; + } + public void setEventName(String eventName) { + this.eventName = eventName; + } + + /** + * If true, publish the event related data to the fraud detector. + **/ + public EventConfig enabled(Boolean enabled) { + + this.enabled = enabled; + return this; + } + + @ApiModelProperty(example = "true", value = "If true, publish the event related data to the fraud detector.") + @JsonProperty("enabled") + @Valid + public Boolean getEnabled() { + return enabled; + } + public void setEnabled(Boolean enabled) { + this.enabled = enabled; + } + + /** + **/ + public EventConfig properties(List properties) { + + this.properties = properties; + return this; + } + + @ApiModelProperty(value = "") + @JsonProperty("properties") + @Valid + public List getProperties() { + return properties; + } + public void setProperties(List properties) { + this.properties = properties; + } + + public EventConfig addPropertiesItem(EventProperty propertiesItem) { + if (this.properties == null) { + this.properties = new ArrayList<>(); + } + this.properties.add(propertiesItem); + return this; + } + + + + @Override + public boolean equals(java.lang.Object o) { + + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + EventConfig eventConfig = (EventConfig) o; + return Objects.equals(this.eventName, eventConfig.eventName) && + Objects.equals(this.enabled, eventConfig.enabled) && + Objects.equals(this.properties, eventConfig.properties); + } + + @Override + public int hashCode() { + return Objects.hash(eventName, enabled, properties); + } + + @Override + public String toString() { + + StringBuilder sb = new StringBuilder(); + sb.append("class EventConfig {\n"); + + sb.append(" eventName: ").append(toIndentedString(eventName)).append("\n"); + sb.append(" enabled: ").append(toIndentedString(enabled)).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.configs/org.wso2.carbon.identity.api.server.configs.v1/src/gen/java/org/wso2/carbon/identity/api/server/configs/v1/model/EventProperty.java b/components/org.wso2.carbon.identity.api.server.configs/org.wso2.carbon.identity.api.server.configs.v1/src/gen/java/org/wso2/carbon/identity/api/server/configs/v1/model/EventProperty.java new file mode 100644 index 0000000000..296b1ad96b --- /dev/null +++ b/components/org.wso2.carbon.identity.api.server.configs/org.wso2.carbon.identity.api.server.configs.v1/src/gen/java/org/wso2/carbon/identity/api/server/configs/v1/model/EventProperty.java @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2023, 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.configs.v1.model; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import javax.validation.constraints.*; + + +import io.swagger.annotations.*; +import java.util.Objects; +import javax.validation.Valid; +import javax.xml.bind.annotation.*; + +public class EventProperty { + + private String propertyKey; + private String propertyValue; + + /** + * key of the event property + **/ + public EventProperty propertyKey(String propertyKey) { + + this.propertyKey = propertyKey; + return this; + } + + @ApiModelProperty(example = "propertyKey1", value = "key of the event property") + @JsonProperty("propertyKey") + @Valid + public String getPropertyKey() { + return propertyKey; + } + public void setPropertyKey(String propertyKey) { + this.propertyKey = propertyKey; + } + + /** + * value of the event property + **/ + public EventProperty propertyValue(String propertyValue) { + + this.propertyValue = propertyValue; + return this; + } + + @ApiModelProperty(example = "propertyValue1", value = "value of the event property") + @JsonProperty("propertyValue") + @Valid + public String getPropertyValue() { + return propertyValue; + } + public void setPropertyValue(String propertyValue) { + this.propertyValue = propertyValue; + } + + + + @Override + public boolean equals(java.lang.Object o) { + + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + EventProperty eventProperty = (EventProperty) o; + return Objects.equals(this.propertyKey, eventProperty.propertyKey) && + Objects.equals(this.propertyValue, eventProperty.propertyValue); + } + + @Override + public int hashCode() { + return Objects.hash(propertyKey, propertyValue); + } + + @Override + public String toString() { + + StringBuilder sb = new StringBuilder(); + sb.append("class EventProperty {\n"); + + sb.append(" propertyKey: ").append(toIndentedString(propertyKey)).append("\n"); + sb.append(" propertyValue: ").append(toIndentedString(propertyValue)).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.configs/org.wso2.carbon.identity.api.server.configs.v1/src/gen/java/org/wso2/carbon/identity/api/server/configs/v1/model/FraudDetectionConfig.java b/components/org.wso2.carbon.identity.api.server.configs/org.wso2.carbon.identity.api.server.configs.v1/src/gen/java/org/wso2/carbon/identity/api/server/configs/v1/model/FraudDetectionConfig.java new file mode 100644 index 0000000000..d9bd84e9d8 --- /dev/null +++ b/components/org.wso2.carbon.identity.api.server.configs/org.wso2.carbon.identity.api.server.configs.v1/src/gen/java/org/wso2/carbon/identity/api/server/configs/v1/model/FraudDetectionConfig.java @@ -0,0 +1,176 @@ +/* + * Copyright (c) 2023, 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.configs.v1.model; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import java.util.ArrayList; +import java.util.List; +import org.wso2.carbon.identity.api.server.configs.v1.model.EventConfig; +import javax.validation.constraints.*; + + +import io.swagger.annotations.*; +import java.util.Objects; +import javax.validation.Valid; +import javax.xml.bind.annotation.*; + +public class FraudDetectionConfig { + + private Boolean publishUserInfo; + private Boolean publishDeviceMetadata; + private Boolean logRequestPayload; + private List events = null; + + + /** + * If true, publish user personal information to the fraud detector. + **/ + public FraudDetectionConfig publishUserInfo(Boolean publishUserInfo) { + + this.publishUserInfo = publishUserInfo; + return this; + } + + @ApiModelProperty(example = "true", value = "If true, publish user personal information to the fraud detector.") + @JsonProperty("publishUserInfo") + @Valid + public Boolean getPublishUserInfo() { + return publishUserInfo; + } + public void setPublishUserInfo(Boolean publishUserInfo) { + this.publishUserInfo = publishUserInfo; + } + + /** + * If true, publish device related metadata to the fraud detector. + **/ + public FraudDetectionConfig publishDeviceMetadata(Boolean publishDeviceMetadata) { + + this.publishDeviceMetadata = publishDeviceMetadata; + return this; + } + + @ApiModelProperty(example = "true", value = "If true, publish device related metadata to the fraud detector.") + @JsonProperty("publishDeviceMetadata") + @Valid + public Boolean getPublishDeviceMetadata() { + return publishDeviceMetadata; + } + public void setPublishDeviceMetadata(Boolean publishDeviceMetadata) { + this.publishDeviceMetadata = publishDeviceMetadata; + } + + /** + * If true, log the request payloads sent to the fraud detector. + **/ + public FraudDetectionConfig logRequestPayload(Boolean logRequestPayload) { + + this.logRequestPayload = logRequestPayload; + return this; + } + + @ApiModelProperty(example = "true", value = "If true, log the request payloads sent to the fraud detector.") + @JsonProperty("logRequestPayload") + @Valid + public Boolean getLogRequestPayload() { + return logRequestPayload; + } + public void setLogRequestPayload(Boolean logRequestPayload) { + this.logRequestPayload = logRequestPayload; + } + + /** + **/ + public FraudDetectionConfig events(List events) { + + this.events = events; + return this; + } + + @ApiModelProperty(value = "") + @JsonProperty("events") + @Valid + public List getEvents() { + return events; + } + public void setEvents(List events) { + this.events = events; + } + + public FraudDetectionConfig addEventsItem(EventConfig eventsItem) { + if (this.events == null) { + this.events = new ArrayList<>(); + } + this.events.add(eventsItem); + return this; + } + + + + @Override + public boolean equals(java.lang.Object o) { + + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + FraudDetectionConfig fraudDetectionConfig = (FraudDetectionConfig) o; + return Objects.equals(this.publishUserInfo, fraudDetectionConfig.publishUserInfo) && + Objects.equals(this.publishDeviceMetadata, fraudDetectionConfig.publishDeviceMetadata) && + Objects.equals(this.logRequestPayload, fraudDetectionConfig.logRequestPayload) && + Objects.equals(this.events, fraudDetectionConfig.events); + } + + @Override + public int hashCode() { + return Objects.hash(publishUserInfo, publishDeviceMetadata, logRequestPayload, events); + } + + @Override + public String toString() { + + StringBuilder sb = new StringBuilder(); + sb.append("class FraudDetectionConfig {\n"); + + sb.append(" publishUserInfo: ").append(toIndentedString(publishUserInfo)).append("\n"); + sb.append(" publishDeviceMetadata: ").append(toIndentedString(publishDeviceMetadata)).append("\n"); + sb.append(" logRequestPayload: ").append(toIndentedString(logRequestPayload)).append("\n"); + sb.append(" events: ").append(toIndentedString(events)).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.configs/org.wso2.carbon.identity.api.server.configs.v1/src/main/java/org/wso2/carbon/identity/api/server/configs/v1/core/ServerConfigManagementService.java b/components/org.wso2.carbon.identity.api.server.configs/org.wso2.carbon.identity.api.server.configs.v1/src/main/java/org/wso2/carbon/identity/api/server/configs/v1/core/ServerConfigManagementService.java index adf2d5881d..70da1c601a 100644 --- a/components/org.wso2.carbon.identity.api.server.configs/org.wso2.carbon.identity.api.server.configs.v1/src/main/java/org/wso2/carbon/identity/api/server/configs/v1/core/ServerConfigManagementService.java +++ b/components/org.wso2.carbon.identity.api.server.configs/org.wso2.carbon.identity.api.server.configs.v1/src/main/java/org/wso2/carbon/identity/api/server/configs/v1/core/ServerConfigManagementService.java @@ -48,6 +48,9 @@ import org.wso2.carbon.identity.api.server.configs.v1.model.DCRConfig; import org.wso2.carbon.identity.api.server.configs.v1.model.DCRPatch; import org.wso2.carbon.identity.api.server.configs.v1.model.Endpoint; +import org.wso2.carbon.identity.api.server.configs.v1.model.EventConfig; +import org.wso2.carbon.identity.api.server.configs.v1.model.EventProperty; +import org.wso2.carbon.identity.api.server.configs.v1.model.FraudDetectionConfig; import org.wso2.carbon.identity.api.server.configs.v1.model.ImpersonationConfiguration; import org.wso2.carbon.identity.api.server.configs.v1.model.ImpersonationPatch; import org.wso2.carbon.identity.api.server.configs.v1.model.InboundAuthPassiveSTSConfig; @@ -89,6 +92,12 @@ import org.wso2.carbon.identity.cors.mgt.core.exception.CORSManagementServiceException; import org.wso2.carbon.identity.cors.mgt.core.exception.CORSManagementServiceServerException; import org.wso2.carbon.identity.cors.mgt.core.model.CORSConfiguration; +import org.wso2.carbon.identity.fraud.detection.core.exception.FraudDetectionConfigClientException; +import org.wso2.carbon.identity.fraud.detection.core.exception.FraudDetectionConfigServerException; +import org.wso2.carbon.identity.fraud.detection.core.exception.IdentityFraudDetectionException; +import org.wso2.carbon.identity.fraud.detection.core.model.EventConfigDTO; +import org.wso2.carbon.identity.fraud.detection.core.model.FraudDetectionConfigDTO; +import org.wso2.carbon.identity.fraud.detection.core.service.FraudDetectionConfigsService; import org.wso2.carbon.identity.oauth.dcr.DCRConfigurationMgtService; import org.wso2.carbon.identity.oauth.dcr.exception.DCRMException; import org.wso2.carbon.identity.oauth2.impersonation.exceptions.ImpersonationConfigMgtClientException; @@ -115,6 +124,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; +import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Locale; @@ -140,6 +150,7 @@ public class ServerConfigManagementService { private final ApplicationManagementService applicationManagementService; + private final FraudDetectionConfigsService fraudDetectionConfigsService; private final IdpManager idpManager; private final CORSManagementService corsManagementService; private final RemoteLoggingConfigService remoteLoggingConfigService; @@ -155,7 +166,8 @@ public ServerConfigManagementService(ApplicationManagementService applicationMan RemoteLoggingConfigService remoteLoggingConfigService, ImpersonationConfigMgtService impersonationConfigMgtService, DCRConfigurationMgtService dcrConfigurationMgtService, - JWTClientAuthenticatorMgtService jwtClientAuthenticatorMgtService) { + JWTClientAuthenticatorMgtService jwtClientAuthenticatorMgtService, + FraudDetectionConfigsService fraudDetectionConfigsService) { this.applicationManagementService = applicationManagementService; this.idpManager = idpManager; @@ -164,6 +176,7 @@ public ServerConfigManagementService(ApplicationManagementService applicationMan this.impersonationConfigMgtService = impersonationConfigMgtService; this.dcrConfigurationMgtService = dcrConfigurationMgtService; this.jwtClientAuthenticatorMgtService = jwtClientAuthenticatorMgtService; + this.fraudDetectionConfigsService = fraudDetectionConfigsService; } /** @@ -2017,4 +2030,124 @@ public void deletePassiveSTSInboundAuthConfig() { Constants.ErrorMessage.ERROR_CODE_ERROR_PASSIVE_STS_INBOUND_AUTH_CONFIG_DELETE, null); } } + + public FraudDetectionConfig getFraudDetectionConfigs() { + + String tenantDomain = ContextLoader.getTenantDomainFromContext(); + try { + FraudDetectionConfigDTO fraudDetectionConfigDTO + = fraudDetectionConfigsService.getFraudDetectionConfigs(tenantDomain); + return buildFraudDetectionConfig(fraudDetectionConfigDTO); + } catch (FraudDetectionConfigServerException e) { + throw handleFraudDetectionConfigException(e, + Constants.ErrorMessage.ERROR_CODE_FRAUD_DETECTION_CONFIG_RETRIEVE, null); + } + } + + public FraudDetectionConfig updateFraudDetectionConfigs(FraudDetectionConfig fraudDetectionConfig) { + + String tenantDomain = ContextLoader.getTenantDomainFromContext(); + try { + FraudDetectionConfigDTO fraudDetectionConfigDTO = + fraudDetectionConfigsService.updateFraudDetectionConfigs( + buildFraudDetectionConfigDTO(fraudDetectionConfig), tenantDomain); + return buildFraudDetectionConfig(fraudDetectionConfigDTO); + } catch (FraudDetectionConfigServerException e) { + throw handleFraudDetectionConfigException(e, + Constants.ErrorMessage.ERROR_CODE_FRAUD_DETECTION_CONFIG_UPDATE, null); + } + } + + private FraudDetectionConfig buildFraudDetectionConfig(FraudDetectionConfigDTO dto) { + + FraudDetectionConfig fraudDetectionConfig = new FraudDetectionConfig(); + fraudDetectionConfig.setPublishUserInfo(dto.isPublishUserInfo()); + fraudDetectionConfig.setPublishDeviceMetadata(dto.isPublishDeviceMetadata()); + fraudDetectionConfig.setLogRequestPayload(dto.isLogRequestPayload()); + + List eventConfigs = new ArrayList<>(); + dto.getEvents().forEach((eventName, eventConfigDTO) -> { + + List eventProperties = new ArrayList<>(); + eventConfigDTO.getProperties().forEach((key, value) -> { + + EventProperty eventProperty = new EventProperty(); + eventProperty.setPropertyKey(key); + eventProperty.setPropertyValue(value); + eventProperties.add(eventProperty); + }); + + EventConfig eventConfig = new EventConfig(); + eventConfig.setEventName(eventName); + eventConfig.setEnabled(eventConfigDTO.isEnabled()); + eventConfig.setProperties(eventProperties); + eventConfigs.add(eventConfig); + }); + + fraudDetectionConfig.setEvents(eventConfigs); + return fraudDetectionConfig; + } + + private FraudDetectionConfigDTO buildFraudDetectionConfigDTO(FraudDetectionConfig config) { + + FraudDetectionConfigDTO fraudDetectionConfigDTO = new FraudDetectionConfigDTO(); + fraudDetectionConfigDTO.setPublishUserInfo(config.getPublishUserInfo()); + fraudDetectionConfigDTO.setPublishDeviceMetadata(config.getPublishDeviceMetadata()); + fraudDetectionConfigDTO.setLogRequestPayload(config.getLogRequestPayload()); + + Map eventConfigDTOMap = new HashMap<>(); + config.getEvents().forEach(eventConfig -> { + + Map propertiesMap = new HashMap<>(); + eventConfig.getProperties().forEach(eventProperty -> + propertiesMap.put(eventProperty.getPropertyKey(), eventProperty.getPropertyValue())); + + EventConfigDTO eventConfigDTO = new EventConfigDTO(eventConfig.getEnabled()); + eventConfigDTO.setProperties(propertiesMap); + eventConfigDTOMap.put(eventConfig.getEventName(), eventConfigDTO); + }); + + fraudDetectionConfigDTO.setEvents(eventConfigDTOMap); + + return fraudDetectionConfigDTO; + } + + private APIError handleFraudDetectionConfigException(IdentityFraudDetectionException e, + Constants.ErrorMessage errorEnum, String data) { + + ErrorResponse errorResponse; + Response.Status status; + + if (e instanceof FraudDetectionConfigClientException) { + + errorResponse = getErrorBuilder(errorEnum, data).build(log, e.getMessage()); + if (e.getErrorCode() != null) { + String errorCode = e.getErrorCode(); + errorCode = + errorCode.contains(org.wso2.carbon.identity.api.server.common.Constants.ERROR_CODE_DELIMITER) ? + errorCode : Constants.CONFIG_ERROR_PREFIX + errorCode; + errorResponse.setCode(errorCode); + } + errorResponse.setDescription(e.getMessage()); + status = Response.Status.BAD_REQUEST; + } else if (e instanceof FraudDetectionConfigServerException) { + + errorResponse = getErrorBuilder(errorEnum, data).build(log, e, errorEnum.description()); + if (e.getErrorCode() != null) { + String errorCode = e.getErrorCode(); + errorCode = + errorCode.contains(org.wso2.carbon.identity.api.server.common.Constants.ERROR_CODE_DELIMITER) ? + errorCode : Constants.CONFIG_ERROR_PREFIX + errorCode; + errorResponse.setCode(errorCode); + } + errorResponse.setDescription(e.getMessage()); + status = Response.Status.INTERNAL_SERVER_ERROR; + } else { + + errorResponse = getErrorBuilder(errorEnum, data).build(log, e, errorEnum.description()); + status = Response.Status.INTERNAL_SERVER_ERROR; + } + + return new APIError(status, errorResponse); + } } diff --git a/components/org.wso2.carbon.identity.api.server.configs/org.wso2.carbon.identity.api.server.configs.v1/src/main/java/org/wso2/carbon/identity/api/server/configs/v1/factories/ServerConfigManagementServiceFactory.java b/components/org.wso2.carbon.identity.api.server.configs/org.wso2.carbon.identity.api.server.configs.v1/src/main/java/org/wso2/carbon/identity/api/server/configs/v1/factories/ServerConfigManagementServiceFactory.java index f4c5e4fc76..dcc76b4eae 100644 --- a/components/org.wso2.carbon.identity.api.server.configs/org.wso2.carbon.identity.api.server.configs.v1/src/main/java/org/wso2/carbon/identity/api/server/configs/v1/factories/ServerConfigManagementServiceFactory.java +++ b/components/org.wso2.carbon.identity.api.server.configs/org.wso2.carbon.identity.api.server.configs.v1/src/main/java/org/wso2/carbon/identity/api/server/configs/v1/factories/ServerConfigManagementServiceFactory.java @@ -4,6 +4,7 @@ import org.wso2.carbon.identity.api.server.configs.v1.core.ServerConfigManagementService; import org.wso2.carbon.identity.application.mgt.ApplicationManagementService; import org.wso2.carbon.identity.cors.mgt.core.CORSManagementService; +import org.wso2.carbon.identity.fraud.detection.core.service.FraudDetectionConfigsService; import org.wso2.carbon.identity.oauth.dcr.DCRConfigurationMgtService; import org.wso2.carbon.identity.oauth2.impersonation.services.ImpersonationConfigMgtService; import org.wso2.carbon.identity.oauth2.token.handler.clientauth.jwt.core.JWTClientAuthenticatorMgtService; @@ -30,6 +31,8 @@ public class ServerConfigManagementServiceFactory { JWTClientAuthenticatorMgtService jwtClientAuthenticatorMgtService = ConfigsServiceHolder .getJWTClientAuthenticatorMgtService(); DCRConfigurationMgtService dcrConfigurationMgtService = ConfigsServiceHolder.getDcrConfigurationMgtService(); + FraudDetectionConfigsService fraudDetectionConfigsService = ConfigsServiceHolder + .getFraudDetectionConfigsService(); if (applicationManagementService == null) { throw new IllegalStateException("ApplicationManagementService is not available from OSGi context."); @@ -59,12 +62,17 @@ public class ServerConfigManagementServiceFactory { throw new IllegalStateException("DCRConfigurationMgtService is not available from OSGi context."); } + if (fraudDetectionConfigsService == null) { + throw new IllegalStateException("FraudDetectionConfigsService is not available from OSGi context."); + } + SERVICE = new ServerConfigManagementService(applicationManagementService, identityProviderManager, corsManagementService, remoteLoggingConfigService, impersonationConfigMgtService, dcrConfigurationMgtService, - jwtClientAuthenticatorMgtService); + jwtClientAuthenticatorMgtService, + fraudDetectionConfigsService); } /** diff --git a/components/org.wso2.carbon.identity.api.server.configs/org.wso2.carbon.identity.api.server.configs.v1/src/main/java/org/wso2/carbon/identity/api/server/configs/v1/impl/ConfigsApiServiceImpl.java b/components/org.wso2.carbon.identity.api.server.configs/org.wso2.carbon.identity.api.server.configs.v1/src/main/java/org/wso2/carbon/identity/api/server/configs/v1/impl/ConfigsApiServiceImpl.java index 0fb96e454e..9622aebd1e 100644 --- a/components/org.wso2.carbon.identity.api.server.configs/org.wso2.carbon.identity.api.server.configs.v1/src/main/java/org/wso2/carbon/identity/api/server/configs/v1/impl/ConfigsApiServiceImpl.java +++ b/components/org.wso2.carbon.identity.api.server.configs/org.wso2.carbon.identity.api.server.configs.v1/src/main/java/org/wso2/carbon/identity/api/server/configs/v1/impl/ConfigsApiServiceImpl.java @@ -23,6 +23,7 @@ import org.wso2.carbon.identity.api.server.configs.v1.factories.ServerConfigManagementServiceFactory; import org.wso2.carbon.identity.api.server.configs.v1.model.CORSPatch; import org.wso2.carbon.identity.api.server.configs.v1.model.DCRPatch; +import org.wso2.carbon.identity.api.server.configs.v1.model.FraudDetectionConfig; import org.wso2.carbon.identity.api.server.configs.v1.model.ImpersonationPatch; import org.wso2.carbon.identity.api.server.configs.v1.model.InboundAuthPassiveSTSConfig; import org.wso2.carbon.identity.api.server.configs.v1.model.InboundAuthSAML2Config; @@ -131,6 +132,12 @@ public Response getRemoteLoggingConfigs() { .collect(Collectors.toList())).build(); } + @Override + public Response getFraudDetectionConfigs() { + + return Response.ok().entity(configManagementService.getFraudDetectionConfigs()).build(); + } + @Override public Response patchPrivatKeyJWTValidationConfiguration(List jwTKeyValidatorPatch) { @@ -220,6 +227,12 @@ public Response updateRemoteLoggingConfigs(List rem return Response.accepted().build(); } + @Override + public Response updateFraudDetectionConfigs(FraudDetectionConfig fraudDetectionConfig) { + + return Response.ok().entity(configManagementService.updateFraudDetectionConfigs(fraudDetectionConfig)).build(); + } + @Override public Response getSAMLInboundAuthConfig() { diff --git a/components/org.wso2.carbon.identity.api.server.configs/org.wso2.carbon.identity.api.server.configs.v1/src/main/resources/configs.yaml b/components/org.wso2.carbon.identity.api.server.configs/org.wso2.carbon.identity.api.server.configs.v1/src/main/resources/configs.yaml index 6f8517447a..794545db66 100644 --- a/components/org.wso2.carbon.identity.api.server.configs/org.wso2.carbon.identity.api.server.configs.v1/src/main/resources/configs.yaml +++ b/components/org.wso2.carbon.identity.api.server.configs/org.wso2.carbon.identity.api.server.configs.v1/src/main/resources/configs.yaml @@ -1121,6 +1121,83 @@ paths: application/json: schema: $ref: '#/components/schemas/Error' + /configs/fraud-detection: + get: + tags: + - Fraud Detection + summary: Get fraud detection configs. + operationId: getFraudDetectionConfigs + description: Retrieve fraud detection related configurations of a tenant. + responses: + '200': + description: Successfully retrieved. + content: + application/json: + schema: + $ref: '#/components/schemas/FraudDetectionConfig' + '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' + put: + tags: + - Fraud Detection + summary: Update fraud detection configs. + operationId: updateFraudDetectionConfigs + description: Update fraud detection related configuration of a tenant. + responses: + '200': + description: Successfully updated. + content: + application/json: + schema: + $ref: '#/components/schemas/FraudDetectionConfig' + '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' + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/FraudDetectionConfig' + required: true servers: - url: 'https://localhost:9443/t/{tenant-domain}/api/server/v1' variables: @@ -1506,6 +1583,51 @@ components: type: boolean description: If true, then email notification will sent to user when impersonation starts. example: true + FraudDetectionConfig: + type: object + properties: + publishUserInfo: + type: boolean + description: 'If true, publish user personal information to the fraud detector.' + example: true + publishDeviceMetadata: + type: boolean + description: 'If true, publish device related metadata to the fraud detector.' + example: true + logRequestPayload: + type: boolean + description: 'If true, log the request payloads sent to the fraud detector.' + example: true + events: + type: array + items: + $ref: '#/components/schemas/EventConfig' + EventConfig: + type: object + properties: + eventName: + type: string + description: 'Name of the event' + example: 'Event.User_registration' + enabled: + type: boolean + description: 'If true, publish the event related data to the fraud detector.' + example: true + properties: + type: array + items: + $ref: '#/components/schemas/EventProperty' + EventProperty: + type: object + properties: + propertyKey: + type: string + description: 'key of the event property' + example: 'propertyKey1' + propertyValue: + type: string + description: 'value of the event property' + example: 'propertyValue1' CORSPatchRequest: type: array items: diff --git a/pom.xml b/pom.xml index 5b2e6e9c0c..75a807af9d 100644 --- a/pom.xml +++ b/pom.xml @@ -545,6 +545,12 @@ ${org.wso2.carbon.logging.service.version} provided + + org.wso2.carbon.identity.framework + org.wso2.carbon.identity.fraud.detection.core + ${carbon.identity.framework.version} + provided + org.wso2.carbon.identity.fetch.remote org.wso2.carbon.identity.remotefetch.core