diff --git a/components/org.wso2.carbon.identity.api.user.recovery/src/gen/java/org/wso2/carbon/identity/recovery/endpoint/SecurityQuestionApi.java b/components/org.wso2.carbon.identity.api.user.recovery/src/gen/java/org/wso2/carbon/identity/recovery/endpoint/SecurityQuestionApi.java deleted file mode 100644 index b358dbdbe2..0000000000 --- a/components/org.wso2.carbon.identity.api.user.recovery/src/gen/java/org/wso2/carbon/identity/recovery/endpoint/SecurityQuestionApi.java +++ /dev/null @@ -1,50 +0,0 @@ -package org.wso2.carbon.identity.recovery.endpoint; - -import org.wso2.carbon.identity.recovery.endpoint.dto.*; -import org.wso2.carbon.identity.recovery.endpoint.SecurityQuestionApiService; -import org.wso2.carbon.identity.recovery.endpoint.factories.SecurityQuestionApiServiceFactory; - -import io.swagger.annotations.ApiParam; - -import org.wso2.carbon.identity.recovery.endpoint.dto.InitiateQuestionResponseDTO; -import org.wso2.carbon.identity.recovery.endpoint.dto.ErrorDTO; - -import java.util.List; - -import java.io.InputStream; -import org.apache.cxf.jaxrs.ext.multipart.Attachment; -import org.apache.cxf.jaxrs.ext.multipart.Multipart; - -import javax.ws.rs.core.Response; -import javax.ws.rs.*; - -@Path("/security-question") -@Consumes({ "application/json" }) -@Produces({ "application/json" }) -@io.swagger.annotations.Api(value = "/security-question", description = "the security-question API") -public class SecurityQuestionApi { - - private final SecurityQuestionApiService delegate = SecurityQuestionApiServiceFactory.getSecurityQuestionApi(); - - @GET - - @Consumes({ "application/json" }) - @Produces({ "application/json" }) - @io.swagger.annotations.ApiOperation(value = "", notes = "This API is used to initiate password recovery using user challenge questions. Response will be a random challenge question with a confirmation key.\n", response = InitiateQuestionResponseDTO.class) - @io.swagger.annotations.ApiResponses(value = { - @io.swagger.annotations.ApiResponse(code = 200, message = "Successful response"), - - @io.swagger.annotations.ApiResponse(code = 204, message = "No content"), - - @io.swagger.annotations.ApiResponse(code = 400, message = "Bad Request"), - - @io.swagger.annotations.ApiResponse(code = 500, message = "Server Error") }) - - public Response securityQuestionGet(@ApiParam(value = "username of the user",required=true) @QueryParam("username") String username, - @ApiParam(value = "`User Store Domain` which user belongs. If not specified, it will be `PRIMARY` domain.\n") @QueryParam("realm") String realm, - @ApiParam(value = "`Tenant Domain` which user belongs. If not specified, it will be `carbon.super` domain.\n") @QueryParam("tenant-domain") String tenantDomain) - { - return delegate.securityQuestionGet(username,realm,tenantDomain); - } -} - diff --git a/components/org.wso2.carbon.identity.api.user.recovery/src/gen/java/org/wso2/carbon/identity/recovery/endpoint/SecurityQuestionApiService.java b/components/org.wso2.carbon.identity.api.user.recovery/src/gen/java/org/wso2/carbon/identity/recovery/endpoint/SecurityQuestionApiService.java deleted file mode 100644 index 451674643c..0000000000 --- a/components/org.wso2.carbon.identity.api.user.recovery/src/gen/java/org/wso2/carbon/identity/recovery/endpoint/SecurityQuestionApiService.java +++ /dev/null @@ -1,19 +0,0 @@ -package org.wso2.carbon.identity.recovery.endpoint; - -import org.wso2.carbon.identity.recovery.endpoint.*; -import org.wso2.carbon.identity.recovery.endpoint.dto.*; - -import org.wso2.carbon.identity.recovery.endpoint.dto.InitiateQuestionResponseDTO; -import org.wso2.carbon.identity.recovery.endpoint.dto.ErrorDTO; - -import java.util.List; - -import java.io.InputStream; -import org.apache.cxf.jaxrs.ext.multipart.Attachment; - -import javax.ws.rs.core.Response; - -public abstract class SecurityQuestionApiService { - public abstract Response securityQuestionGet(String username,String realm,String tenantDomain); -} - diff --git a/components/org.wso2.carbon.identity.api.user.recovery/src/gen/java/org/wso2/carbon/identity/recovery/endpoint/SecurityQuestionsApi.java b/components/org.wso2.carbon.identity.api.user.recovery/src/gen/java/org/wso2/carbon/identity/recovery/endpoint/SecurityQuestionsApi.java deleted file mode 100644 index 84a0ec584c..0000000000 --- a/components/org.wso2.carbon.identity.api.user.recovery/src/gen/java/org/wso2/carbon/identity/recovery/endpoint/SecurityQuestionsApi.java +++ /dev/null @@ -1,50 +0,0 @@ -package org.wso2.carbon.identity.recovery.endpoint; - -import org.wso2.carbon.identity.recovery.endpoint.dto.*; -import org.wso2.carbon.identity.recovery.endpoint.SecurityQuestionsApiService; -import org.wso2.carbon.identity.recovery.endpoint.factories.SecurityQuestionsApiServiceFactory; - -import io.swagger.annotations.ApiParam; - -import org.wso2.carbon.identity.recovery.endpoint.dto.InitiateAllQuestionResponseDTO; -import org.wso2.carbon.identity.recovery.endpoint.dto.ErrorDTO; - -import java.util.List; - -import java.io.InputStream; -import org.apache.cxf.jaxrs.ext.multipart.Attachment; -import org.apache.cxf.jaxrs.ext.multipart.Multipart; - -import javax.ws.rs.core.Response; -import javax.ws.rs.*; - -@Path("/security-questions") -@Consumes({ "application/json" }) -@Produces({ "application/json" }) -@io.swagger.annotations.Api(value = "/security-questions", description = "the security-questions API") -public class SecurityQuestionsApi { - - private final SecurityQuestionsApiService delegate = SecurityQuestionsApiServiceFactory.getSecurityQuestionsApi(); - - @GET - - @Consumes({ "application/json" }) - @Produces({ "application/json" }) - @io.swagger.annotations.ApiOperation(value = "", notes = "This API is used to initiate password recovery using user challenge questions at once. Response will be a random challenge questions with a confirmation key.\n", response = InitiateAllQuestionResponseDTO.class) - @io.swagger.annotations.ApiResponses(value = { - @io.swagger.annotations.ApiResponse(code = 200, message = "Successful response"), - - @io.swagger.annotations.ApiResponse(code = 204, message = "No content"), - - @io.swagger.annotations.ApiResponse(code = 400, message = "Bad Request"), - - @io.swagger.annotations.ApiResponse(code = 500, message = "Server Error") }) - - public Response securityQuestionsGet(@ApiParam(value = "username of the user",required=true) @QueryParam("username") String username, - @ApiParam(value = "`User Store Domain` which user belongs. If not specified, it will be `PRIMARY` domain.\n") @QueryParam("realm") String realm, - @ApiParam(value = "`Tenant Domain` which user belongs. If not specified, it will be `carbon.super` domain.\n") @QueryParam("tenant-domain") String tenantDomain) - { - return delegate.securityQuestionsGet(username,realm,tenantDomain); - } -} - diff --git a/components/org.wso2.carbon.identity.api.user.recovery/src/gen/java/org/wso2/carbon/identity/recovery/endpoint/SecurityQuestionsApiService.java b/components/org.wso2.carbon.identity.api.user.recovery/src/gen/java/org/wso2/carbon/identity/recovery/endpoint/SecurityQuestionsApiService.java deleted file mode 100644 index c63c2cfa1b..0000000000 --- a/components/org.wso2.carbon.identity.api.user.recovery/src/gen/java/org/wso2/carbon/identity/recovery/endpoint/SecurityQuestionsApiService.java +++ /dev/null @@ -1,19 +0,0 @@ -package org.wso2.carbon.identity.recovery.endpoint; - -import org.wso2.carbon.identity.recovery.endpoint.*; -import org.wso2.carbon.identity.recovery.endpoint.dto.*; - -import org.wso2.carbon.identity.recovery.endpoint.dto.InitiateAllQuestionResponseDTO; -import org.wso2.carbon.identity.recovery.endpoint.dto.ErrorDTO; - -import java.util.List; - -import java.io.InputStream; -import org.apache.cxf.jaxrs.ext.multipart.Attachment; - -import javax.ws.rs.core.Response; - -public abstract class SecurityQuestionsApiService { - public abstract Response securityQuestionsGet(String username,String realm,String tenantDomain); -} - diff --git a/components/org.wso2.carbon.identity.api.user.recovery/src/gen/java/org/wso2/carbon/identity/recovery/endpoint/ValidateAnswerApi.java b/components/org.wso2.carbon.identity.api.user.recovery/src/gen/java/org/wso2/carbon/identity/recovery/endpoint/ValidateAnswerApi.java deleted file mode 100644 index 087d93d753..0000000000 --- a/components/org.wso2.carbon.identity.api.user.recovery/src/gen/java/org/wso2/carbon/identity/recovery/endpoint/ValidateAnswerApi.java +++ /dev/null @@ -1,48 +0,0 @@ -package org.wso2.carbon.identity.recovery.endpoint; - -import org.wso2.carbon.identity.recovery.endpoint.dto.*; -import org.wso2.carbon.identity.recovery.endpoint.ValidateAnswerApiService; -import org.wso2.carbon.identity.recovery.endpoint.factories.ValidateAnswerApiServiceFactory; - -import io.swagger.annotations.ApiParam; - -import org.wso2.carbon.identity.recovery.endpoint.dto.InitiateQuestionResponseDTO; -import org.wso2.carbon.identity.recovery.endpoint.dto.ErrorDTO; -import org.wso2.carbon.identity.recovery.endpoint.dto.AnswerVerificationRequestDTO; -import org.wso2.carbon.identity.recovery.endpoint.dto.RetryErrorDTO; - -import java.util.List; - -import java.io.InputStream; -import org.apache.cxf.jaxrs.ext.multipart.Attachment; -import org.apache.cxf.jaxrs.ext.multipart.Multipart; - -import javax.ws.rs.core.Response; -import javax.ws.rs.*; - -@Path("/validate-answer") -@Consumes({ "application/json" }) -@Produces({ "application/json" }) -@io.swagger.annotations.Api(value = "/validate-answer", description = "the validate-answer API") -public class ValidateAnswerApi { - - private final ValidateAnswerApiService delegate = ValidateAnswerApiServiceFactory.getValidateAnswerApi(); - - @POST - - @Consumes({ "application/json" }) - @Produces({ "application/json" }) - @io.swagger.annotations.ApiOperation(value = "", notes = "This is used to validate user challenge answer. If user challenge answer is valid, it will send another challenge question to answer until the status become `COMPLETE`. If the answer is wrong, user can retry the answer.\n", response = InitiateQuestionResponseDTO.class) - @io.swagger.annotations.ApiResponses(value = { - @io.swagger.annotations.ApiResponse(code = 200, message = "Successful response"), - - @io.swagger.annotations.ApiResponse(code = 400, message = "Bad Request"), - - @io.swagger.annotations.ApiResponse(code = 500, message = "Server Error") }) - - public Response validateAnswerPost(@ApiParam(value = "User answers verification with key returned in privious step." ,required=true ) AnswerVerificationRequestDTO answerVerificationRequest) - { - return delegate.validateAnswerPost(answerVerificationRequest); - } -} - diff --git a/components/org.wso2.carbon.identity.api.user.recovery/src/gen/java/org/wso2/carbon/identity/recovery/endpoint/ValidateAnswerApiService.java b/components/org.wso2.carbon.identity.api.user.recovery/src/gen/java/org/wso2/carbon/identity/recovery/endpoint/ValidateAnswerApiService.java deleted file mode 100644 index 5e41ad814d..0000000000 --- a/components/org.wso2.carbon.identity.api.user.recovery/src/gen/java/org/wso2/carbon/identity/recovery/endpoint/ValidateAnswerApiService.java +++ /dev/null @@ -1,21 +0,0 @@ -package org.wso2.carbon.identity.recovery.endpoint; - -import org.wso2.carbon.identity.recovery.endpoint.*; -import org.wso2.carbon.identity.recovery.endpoint.dto.*; - -import org.wso2.carbon.identity.recovery.endpoint.dto.InitiateQuestionResponseDTO; -import org.wso2.carbon.identity.recovery.endpoint.dto.ErrorDTO; -import org.wso2.carbon.identity.recovery.endpoint.dto.AnswerVerificationRequestDTO; -import org.wso2.carbon.identity.recovery.endpoint.dto.RetryErrorDTO; - -import java.util.List; - -import java.io.InputStream; -import org.apache.cxf.jaxrs.ext.multipart.Attachment; - -import javax.ws.rs.core.Response; - -public abstract class ValidateAnswerApiService { - public abstract Response validateAnswerPost(AnswerVerificationRequestDTO answerVerificationRequest); -} - diff --git a/components/org.wso2.carbon.identity.api.user.recovery/src/gen/java/org/wso2/carbon/identity/recovery/endpoint/dto/AnswerVerificationRequestDTO.java b/components/org.wso2.carbon.identity.api.user.recovery/src/gen/java/org/wso2/carbon/identity/recovery/endpoint/dto/AnswerVerificationRequestDTO.java deleted file mode 100644 index 3c177f5077..0000000000 --- a/components/org.wso2.carbon.identity.api.user.recovery/src/gen/java/org/wso2/carbon/identity/recovery/endpoint/dto/AnswerVerificationRequestDTO.java +++ /dev/null @@ -1,79 +0,0 @@ -package org.wso2.carbon.identity.recovery.endpoint.dto; - -import java.util.ArrayList; -import java.util.List; -import org.wso2.carbon.identity.recovery.endpoint.dto.PropertyDTO; -import org.wso2.carbon.identity.recovery.endpoint.dto.SecurityAnswerDTO; - -import io.swagger.annotations.*; -import com.fasterxml.jackson.annotation.*; - -import javax.validation.constraints.NotNull; - - - - - -@ApiModel(description = "") -public class AnswerVerificationRequestDTO { - - - - private String key = null; - - - private List answers = new ArrayList(); - - - private List properties = new ArrayList(); - - - /** - **/ - @ApiModelProperty(value = "") - @JsonProperty("key") - public String getKey() { - return key; - } - public void setKey(String key) { - this.key = key; - } - - - /** - **/ - @ApiModelProperty(value = "") - @JsonProperty("answers") - public List getAnswers() { - return answers; - } - public void setAnswers(List answers) { - this.answers = answers; - } - - - /** - **/ - @ApiModelProperty(value = "") - @JsonProperty("properties") - public List getProperties() { - return properties; - } - public void setProperties(List properties) { - this.properties = properties; - } - - - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append("class AnswerVerificationRequestDTO {\n"); - - sb.append(" key: ").append(key).append("\n"); - sb.append(" answers: ").append(answers).append("\n"); - sb.append(" properties: ").append(properties).append("\n"); - sb.append("}\n"); - return sb.toString(); - } -} diff --git a/components/org.wso2.carbon.identity.api.user.recovery/src/gen/java/org/wso2/carbon/identity/recovery/endpoint/dto/InitiateAllQuestionResponseDTO.java b/components/org.wso2.carbon.identity.api.user.recovery/src/gen/java/org/wso2/carbon/identity/recovery/endpoint/dto/InitiateAllQuestionResponseDTO.java deleted file mode 100644 index 261d50314a..0000000000 --- a/components/org.wso2.carbon.identity.api.user.recovery/src/gen/java/org/wso2/carbon/identity/recovery/endpoint/dto/InitiateAllQuestionResponseDTO.java +++ /dev/null @@ -1,79 +0,0 @@ -package org.wso2.carbon.identity.recovery.endpoint.dto; - -import java.util.ArrayList; -import java.util.List; -import org.wso2.carbon.identity.recovery.endpoint.dto.LinkDTO; -import org.wso2.carbon.identity.recovery.endpoint.dto.QuestionDTO; - -import io.swagger.annotations.*; -import com.fasterxml.jackson.annotation.*; - -import javax.validation.constraints.NotNull; - - - - - -@ApiModel(description = "") -public class InitiateAllQuestionResponseDTO { - - - - private String key = null; - - - private List questions = new ArrayList(); - - - private LinkDTO link = null; - - - /** - **/ - @ApiModelProperty(value = "") - @JsonProperty("key") - public String getKey() { - return key; - } - public void setKey(String key) { - this.key = key; - } - - - /** - **/ - @ApiModelProperty(value = "") - @JsonProperty("questions") - public List getQuestions() { - return questions; - } - public void setQuestions(List questions) { - this.questions = questions; - } - - - /** - **/ - @ApiModelProperty(value = "") - @JsonProperty("link") - public LinkDTO getLink() { - return link; - } - public void setLink(LinkDTO link) { - this.link = link; - } - - - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append("class InitiateAllQuestionResponseDTO {\n"); - - sb.append(" key: ").append(key).append("\n"); - sb.append(" questions: ").append(questions).append("\n"); - sb.append(" link: ").append(link).append("\n"); - sb.append("}\n"); - return sb.toString(); - } -} diff --git a/components/org.wso2.carbon.identity.api.user.recovery/src/gen/java/org/wso2/carbon/identity/recovery/endpoint/dto/InitiateQuestionResponseDTO.java b/components/org.wso2.carbon.identity.api.user.recovery/src/gen/java/org/wso2/carbon/identity/recovery/endpoint/dto/InitiateQuestionResponseDTO.java deleted file mode 100644 index 5d2ac63035..0000000000 --- a/components/org.wso2.carbon.identity.api.user.recovery/src/gen/java/org/wso2/carbon/identity/recovery/endpoint/dto/InitiateQuestionResponseDTO.java +++ /dev/null @@ -1,77 +0,0 @@ -package org.wso2.carbon.identity.recovery.endpoint.dto; - -import org.wso2.carbon.identity.recovery.endpoint.dto.LinkDTO; -import org.wso2.carbon.identity.recovery.endpoint.dto.QuestionDTO; - -import io.swagger.annotations.*; -import com.fasterxml.jackson.annotation.*; - -import javax.validation.constraints.NotNull; - - - - - -@ApiModel(description = "") -public class InitiateQuestionResponseDTO { - - - - private String key = null; - - - private QuestionDTO question = null; - - - private LinkDTO link = null; - - - /** - **/ - @ApiModelProperty(value = "") - @JsonProperty("key") - public String getKey() { - return key; - } - public void setKey(String key) { - this.key = key; - } - - - /** - **/ - @ApiModelProperty(value = "") - @JsonProperty("question") - public QuestionDTO getQuestion() { - return question; - } - public void setQuestion(QuestionDTO question) { - this.question = question; - } - - - /** - **/ - @ApiModelProperty(value = "") - @JsonProperty("link") - public LinkDTO getLink() { - return link; - } - public void setLink(LinkDTO link) { - this.link = link; - } - - - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append("class InitiateQuestionResponseDTO {\n"); - - sb.append(" key: ").append(key).append("\n"); - sb.append(" question: ").append(question).append("\n"); - sb.append(" link: ").append(link).append("\n"); - sb.append("}\n"); - return sb.toString(); - } -} diff --git a/components/org.wso2.carbon.identity.api.user.recovery/src/gen/java/org/wso2/carbon/identity/recovery/endpoint/dto/QuestionDTO.java b/components/org.wso2.carbon.identity.api.user.recovery/src/gen/java/org/wso2/carbon/identity/recovery/endpoint/dto/QuestionDTO.java deleted file mode 100644 index ede3c7227a..0000000000 --- a/components/org.wso2.carbon.identity.api.user.recovery/src/gen/java/org/wso2/carbon/identity/recovery/endpoint/dto/QuestionDTO.java +++ /dev/null @@ -1,59 +0,0 @@ -package org.wso2.carbon.identity.recovery.endpoint.dto; - - -import io.swagger.annotations.*; -import com.fasterxml.jackson.annotation.*; - -import javax.validation.constraints.NotNull; - - - - - -@ApiModel(description = "") -public class QuestionDTO { - - - - private String question = null; - - - private String questionSetId = null; - - - /** - **/ - @ApiModelProperty(value = "") - @JsonProperty("question") - public String getQuestion() { - return question; - } - public void setQuestion(String question) { - this.question = question; - } - - - /** - **/ - @ApiModelProperty(value = "") - @JsonProperty("question-set-id") - public String getQuestionSetId() { - return questionSetId; - } - public void setQuestionSetId(String questionSetId) { - this.questionSetId = questionSetId; - } - - - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append("class QuestionDTO {\n"); - - sb.append(" question: ").append(question).append("\n"); - sb.append(" questionSetId: ").append(questionSetId).append("\n"); - sb.append("}\n"); - return sb.toString(); - } -} diff --git a/components/org.wso2.carbon.identity.api.user.recovery/src/gen/java/org/wso2/carbon/identity/recovery/endpoint/dto/SecurityAnswerDTO.java b/components/org.wso2.carbon.identity.api.user.recovery/src/gen/java/org/wso2/carbon/identity/recovery/endpoint/dto/SecurityAnswerDTO.java deleted file mode 100644 index 4f14fc66bc..0000000000 --- a/components/org.wso2.carbon.identity.api.user.recovery/src/gen/java/org/wso2/carbon/identity/recovery/endpoint/dto/SecurityAnswerDTO.java +++ /dev/null @@ -1,59 +0,0 @@ -package org.wso2.carbon.identity.recovery.endpoint.dto; - - -import io.swagger.annotations.*; -import com.fasterxml.jackson.annotation.*; - -import javax.validation.constraints.NotNull; - - - - - -@ApiModel(description = "") -public class SecurityAnswerDTO { - - - - private String questionSetId = null; - - - private String answer = null; - - - /** - **/ - @ApiModelProperty(value = "") - @JsonProperty("question-set-id") - public String getQuestionSetId() { - return questionSetId; - } - public void setQuestionSetId(String questionSetId) { - this.questionSetId = questionSetId; - } - - - /** - **/ - @ApiModelProperty(value = "") - @JsonProperty("answer") - public String getAnswer() { - return answer; - } - public void setAnswer(String answer) { - this.answer = answer; - } - - - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append("class SecurityAnswerDTO {\n"); - - sb.append(" questionSetId: ").append(questionSetId).append("\n"); - sb.append(" answer: ").append(answer).append("\n"); - sb.append("}\n"); - return sb.toString(); - } -} diff --git a/components/org.wso2.carbon.identity.api.user.recovery/src/gen/java/org/wso2/carbon/identity/recovery/endpoint/factories/SecurityQuestionApiServiceFactory.java b/components/org.wso2.carbon.identity.api.user.recovery/src/gen/java/org/wso2/carbon/identity/recovery/endpoint/factories/SecurityQuestionApiServiceFactory.java deleted file mode 100644 index 9427ac5280..0000000000 --- a/components/org.wso2.carbon.identity.api.user.recovery/src/gen/java/org/wso2/carbon/identity/recovery/endpoint/factories/SecurityQuestionApiServiceFactory.java +++ /dev/null @@ -1,14 +0,0 @@ -package org.wso2.carbon.identity.recovery.endpoint.factories; - -import org.wso2.carbon.identity.recovery.endpoint.SecurityQuestionApiService; -import org.wso2.carbon.identity.recovery.endpoint.impl.SecurityQuestionApiServiceImpl; - -public class SecurityQuestionApiServiceFactory { - - private final static SecurityQuestionApiService service = new SecurityQuestionApiServiceImpl(); - - public static SecurityQuestionApiService getSecurityQuestionApi() - { - return service; - } -} diff --git a/components/org.wso2.carbon.identity.api.user.recovery/src/gen/java/org/wso2/carbon/identity/recovery/endpoint/factories/SecurityQuestionsApiServiceFactory.java b/components/org.wso2.carbon.identity.api.user.recovery/src/gen/java/org/wso2/carbon/identity/recovery/endpoint/factories/SecurityQuestionsApiServiceFactory.java deleted file mode 100644 index b76ba56a51..0000000000 --- a/components/org.wso2.carbon.identity.api.user.recovery/src/gen/java/org/wso2/carbon/identity/recovery/endpoint/factories/SecurityQuestionsApiServiceFactory.java +++ /dev/null @@ -1,14 +0,0 @@ -package org.wso2.carbon.identity.recovery.endpoint.factories; - -import org.wso2.carbon.identity.recovery.endpoint.SecurityQuestionsApiService; -import org.wso2.carbon.identity.recovery.endpoint.impl.SecurityQuestionsApiServiceImpl; - -public class SecurityQuestionsApiServiceFactory { - - private final static SecurityQuestionsApiService service = new SecurityQuestionsApiServiceImpl(); - - public static SecurityQuestionsApiService getSecurityQuestionsApi() - { - return service; - } -} diff --git a/components/org.wso2.carbon.identity.api.user.recovery/src/gen/java/org/wso2/carbon/identity/recovery/endpoint/factories/ValidateAnswerApiServiceFactory.java b/components/org.wso2.carbon.identity.api.user.recovery/src/gen/java/org/wso2/carbon/identity/recovery/endpoint/factories/ValidateAnswerApiServiceFactory.java deleted file mode 100644 index 509635910d..0000000000 --- a/components/org.wso2.carbon.identity.api.user.recovery/src/gen/java/org/wso2/carbon/identity/recovery/endpoint/factories/ValidateAnswerApiServiceFactory.java +++ /dev/null @@ -1,14 +0,0 @@ -package org.wso2.carbon.identity.recovery.endpoint.factories; - -import org.wso2.carbon.identity.recovery.endpoint.ValidateAnswerApiService; -import org.wso2.carbon.identity.recovery.endpoint.impl.ValidateAnswerApiServiceImpl; - -public class ValidateAnswerApiServiceFactory { - - private final static ValidateAnswerApiService service = new ValidateAnswerApiServiceImpl(); - - public static ValidateAnswerApiService getValidateAnswerApi() - { - return service; - } -} diff --git a/components/org.wso2.carbon.identity.api.user.recovery/src/main/java/org/wso2/carbon/identity/recovery/endpoint/Utils/RecoveryUtil.java b/components/org.wso2.carbon.identity.api.user.recovery/src/main/java/org/wso2/carbon/identity/recovery/endpoint/Utils/RecoveryUtil.java index 9d090d0801..9aef837e70 100644 --- a/components/org.wso2.carbon.identity.api.user.recovery/src/main/java/org/wso2/carbon/identity/recovery/endpoint/Utils/RecoveryUtil.java +++ b/components/org.wso2.carbon.identity.api.user.recovery/src/main/java/org/wso2/carbon/identity/recovery/endpoint/Utils/RecoveryUtil.java @@ -19,29 +19,20 @@ import org.wso2.carbon.identity.governance.IdentityGovernanceException; import org.wso2.carbon.identity.governance.IdentityGovernanceService; import org.wso2.carbon.identity.recovery.IdentityRecoveryConstants; -import org.wso2.carbon.identity.recovery.bean.ChallengeQuestionResponse; -import org.wso2.carbon.identity.recovery.bean.ChallengeQuestionsResponse; import org.wso2.carbon.identity.recovery.endpoint.Constants; import org.wso2.carbon.identity.recovery.endpoint.Exceptions.BadRequestException; import org.wso2.carbon.identity.recovery.endpoint.Exceptions.InternalServerErrorException; import org.wso2.carbon.identity.recovery.endpoint.dto.ClaimDTO; import org.wso2.carbon.identity.recovery.endpoint.dto.ErrorDTO; -import org.wso2.carbon.identity.recovery.endpoint.dto.InitiateAllQuestionResponseDTO; -import org.wso2.carbon.identity.recovery.endpoint.dto.InitiateQuestionResponseDTO; import org.wso2.carbon.identity.recovery.endpoint.dto.LinkDTO; import org.wso2.carbon.identity.recovery.endpoint.dto.PropertyDTO; -import org.wso2.carbon.identity.recovery.endpoint.dto.QuestionDTO; import org.wso2.carbon.identity.recovery.endpoint.dto.ReCaptchaResponseTokenDTO; -import org.wso2.carbon.identity.recovery.endpoint.dto.SecurityAnswerDTO; import org.wso2.carbon.identity.recovery.endpoint.dto.UserClaimDTO; import org.wso2.carbon.identity.recovery.endpoint.dto.UserDTO; import org.wso2.carbon.identity.recovery.internal.IdentityRecoveryServiceDataHolder; -import org.wso2.carbon.identity.recovery.model.ChallengeQuestion; import org.wso2.carbon.identity.recovery.model.Property; -import org.wso2.carbon.identity.recovery.model.UserChallengeAnswer; import org.wso2.carbon.identity.recovery.model.UserClaim; import org.wso2.carbon.identity.recovery.password.NotificationPasswordRecoveryManager; -import org.wso2.carbon.identity.recovery.password.SecurityQuestionPasswordRecoveryManager; import org.wso2.carbon.identity.recovery.signup.UserSelfRegistrationManager; import org.wso2.carbon.identity.recovery.username.NotificationUsernameRecoveryManager; import org.wso2.carbon.user.api.Claim; @@ -73,11 +64,6 @@ public static NotificationPasswordRecoveryManager getNotificationBasedPwdRecover .getOSGiService(NotificationPasswordRecoveryManager.class, null); } - public static SecurityQuestionPasswordRecoveryManager getSecurityQuestionBasedPwdRecoveryManager() { - return (SecurityQuestionPasswordRecoveryManager) PrivilegedCarbonContext.getThreadLocalCarbonContext() - .getOSGiService(SecurityQuestionPasswordRecoveryManager.class, null); - } - public static NotificationUsernameRecoveryManager getNotificationBasedUsernameRecoveryManager() { return (NotificationUsernameRecoveryManager) PrivilegedCarbonContext.getThreadLocalCarbonContext() .getOSGiService(NotificationUsernameRecoveryManager.class, null); @@ -224,59 +210,6 @@ public static UserClaim[] getUserClaims(List claimDTOs) { return userClaims; } - public static InitiateQuestionResponseDTO getInitiateQuestionResponseDTO - (ChallengeQuestionResponse challengeQuestionResponse) { - InitiateQuestionResponseDTO initiateQuestionResponseDTO = new InitiateQuestionResponseDTO(); - - QuestionDTO questionDTO = new QuestionDTO(); - - if (challengeQuestionResponse.getQuestion() != null) { - questionDTO.setQuestion(challengeQuestionResponse.getQuestion().getQuestion()); - questionDTO.setQuestionSetId(challengeQuestionResponse.getQuestion().getQuestionSetId()); - - initiateQuestionResponseDTO.setQuestion(questionDTO); - } - - initiateQuestionResponseDTO.setKey(challengeQuestionResponse.getCode()); - - LinkDTO linkDTO = new LinkDTO(); - - if (IdentityRecoveryConstants.RECOVERY_STATUS_COMPLETE.equals(challengeQuestionResponse.getStatus())) { - linkDTO.setRel("set-password"); - linkDTO.setUri("/api/identity/recovery/v0.9"); - } else { - linkDTO.setRel("validate-answer"); - linkDTO.setUri("/api/identity/recovery/v0.9"); - } - - initiateQuestionResponseDTO.setLink(linkDTO); - return initiateQuestionResponseDTO; - } - - public static InitiateAllQuestionResponseDTO getInitiateQuestionResponseDTO - (ChallengeQuestionsResponse challengeQuestionsResponse) { - InitiateAllQuestionResponseDTO initiateAllQuestionResponseDTO = new InitiateAllQuestionResponseDTO(); - - List questionDTOs = new ArrayList<>(); - - for (ChallengeQuestion challengeQuestion : challengeQuestionsResponse.getQuestion()) { - QuestionDTO questionDTO = new QuestionDTO(); - questionDTO.setQuestion(challengeQuestion.getQuestion()); - questionDTO.setQuestionSetId(challengeQuestion.getQuestionSetId()); - questionDTOs.add(questionDTO); - - } - - initiateAllQuestionResponseDTO.setQuestions(questionDTOs); - initiateAllQuestionResponseDTO.setKey(challengeQuestionsResponse.getCode()); - - LinkDTO linkDTO = new LinkDTO(); - linkDTO.setRel("validate-answer"); - linkDTO.setUri("/api/identity/recovery/v0.9"); - initiateAllQuestionResponseDTO.setLink(linkDTO); - return initiateAllQuestionResponseDTO; - } - public static User getUser(UserDTO userDTO) { User user = new User(); user.setTenantDomain(userDTO.getTenantDomain()); @@ -304,21 +237,6 @@ public static UserDTO getUserDTO(User user) { return userDTO; } - public static UserChallengeAnswer[] getUserChallengeAnswers(List securityAnswerDTOs) { - - UserChallengeAnswer[] userChallengeAnswers = new UserChallengeAnswer[securityAnswerDTOs.size()]; - - for (int i = 0; i < securityAnswerDTOs.size(); i++) { - ChallengeQuestion challengeQuestion = new ChallengeQuestion(securityAnswerDTOs.get(i).getQuestionSetId(), - null); - UserChallengeAnswer userChallengeAnswer = new UserChallengeAnswer(challengeQuestion, securityAnswerDTOs - .get(i).getAnswer()); - userChallengeAnswers[i] = userChallengeAnswer; - } - - return userChallengeAnswers; - } - public static Property[] getProperties(List propertyDTOs) { if (propertyDTOs == null) { return new Property[0]; diff --git a/components/org.wso2.carbon.identity.api.user.recovery/src/main/java/org/wso2/carbon/identity/recovery/endpoint/impl/SecurityQuestionApiServiceImpl.java b/components/org.wso2.carbon.identity.api.user.recovery/src/main/java/org/wso2/carbon/identity/recovery/endpoint/impl/SecurityQuestionApiServiceImpl.java deleted file mode 100644 index 4f2afc78ea..0000000000 --- a/components/org.wso2.carbon.identity.api.user.recovery/src/main/java/org/wso2/carbon/identity/recovery/endpoint/impl/SecurityQuestionApiServiceImpl.java +++ /dev/null @@ -1,102 +0,0 @@ -package org.wso2.carbon.identity.recovery.endpoint.impl; - -import org.apache.commons.lang.ArrayUtils; -import org.apache.commons.lang.StringUtils; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.wso2.carbon.base.MultitenantConstants; -import org.wso2.carbon.identity.application.common.model.User; -import org.wso2.carbon.identity.core.util.IdentityTenantUtil; -import org.wso2.carbon.identity.core.util.IdentityUtil; -import org.wso2.carbon.identity.recovery.IdentityRecoveryClientException; -import org.wso2.carbon.identity.recovery.IdentityRecoveryConstants; -import org.wso2.carbon.identity.recovery.IdentityRecoveryException; -import org.wso2.carbon.identity.recovery.bean.ChallengeQuestionResponse; -import org.wso2.carbon.identity.recovery.endpoint.Constants; -import org.wso2.carbon.identity.recovery.endpoint.SecurityQuestionApiService; -import org.wso2.carbon.identity.recovery.endpoint.Utils.RecoveryUtil; -import org.wso2.carbon.identity.recovery.endpoint.dto.InitiateQuestionResponseDTO; -import org.wso2.carbon.identity.recovery.endpoint.dto.UserDTO; -import org.wso2.carbon.identity.recovery.internal.IdentityRecoveryServiceDataHolder; -import org.wso2.carbon.identity.recovery.password.SecurityQuestionPasswordRecoveryManager; -import org.wso2.carbon.user.core.UserStoreConfigConstants; -import org.wso2.carbon.user.core.service.RealmService; - - -import javax.ws.rs.core.Response; -import java.net.MalformedURLException; - -public class SecurityQuestionApiServiceImpl extends SecurityQuestionApiService { - private static final Log LOG = LogFactory.getLog(SecurityQuestionApiServiceImpl.class); - - @Override - public Response securityQuestionGet(String username, String realm, String tenantDomain) { - - if (IdentityUtil.threadLocalProperties.get().get(Constants.TENANT_NAME_FROM_CONTEXT) != null) { - tenantDomain = (String) IdentityUtil.threadLocalProperties.get().get(Constants.TENANT_NAME_FROM_CONTEXT); - } - - User user = new User(); - user.setUserName(username); - - if (StringUtils.isNotBlank(realm)) { - user.setUserStoreDomain(realm); - } else { - user.setUserStoreDomain(UserStoreConfigConstants.PRIMARY); - } - - if (StringUtils.isBlank(tenantDomain)) { - user.setTenantDomain(MultitenantConstants.SUPER_TENANT_DOMAIN_NAME); - } else { - user.setTenantDomain(tenantDomain); - } - - int tenantId = IdentityTenantUtil.getTenantId(user.getTenantDomain()); - - if (StringUtils.isBlank(realm)) { - String[] userList = RecoveryUtil.getUserList(tenantId, username); - - if (ArrayUtils.isEmpty(userList)) { - String msg = "Unable to find an user with username: " + username + " in the system."; - LOG.error(msg); - } else if (userList.length == 1) { - user.setUserStoreDomain(IdentityUtil.extractDomainFromName(userList[0])); - } else { - String msg = "There are multiple users with username: " + username + " in the system, " + - "please send the correct user-store domain along with the username."; - LOG.error(msg); - RecoveryUtil.handleBadRequest(msg, Constants.ERROR_CODE_MULTIPLE_USERS_MATCHING); - } - } - - InitiateQuestionResponseDTO initiateQuestionResponseDTO = null; - - SecurityQuestionPasswordRecoveryManager securityQuestionBasedPwdRecoveryManager = - RecoveryUtil.getSecurityQuestionBasedPwdRecoveryManager(); - - try { - ChallengeQuestionResponse challengeQuestionResponse = securityQuestionBasedPwdRecoveryManager - .initiateUserChallengeQuestion(user); - initiateQuestionResponseDTO = RecoveryUtil.getInitiateQuestionResponseDTO(challengeQuestionResponse); - } catch (IdentityRecoveryClientException e) { - if (LOG.isDebugEnabled()) { - LOG.debug("Client Error while initiating password recovery flow using security questions ", e); - } - - if (IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_CHALLENGE_QUESTION_NOT_FOUND.getCode() - .equals(e.getErrorCode())) { - return Response.noContent().build(); - } - - RecoveryUtil.handleBadRequest(e.getMessage(), e.getErrorCode()); - - } catch (IdentityRecoveryException e) { - RecoveryUtil.handleInternalServerError(Constants.SERVER_ERROR, e.getErrorCode(), LOG, e); - - } catch (Throwable throwable) { - RecoveryUtil.handleInternalServerError(Constants.SERVER_ERROR, IdentityRecoveryConstants - .ErrorMessages.ERROR_CODE_UNEXPECTED.getCode(), LOG, throwable); - } - return Response.accepted(initiateQuestionResponseDTO).build(); - } -} diff --git a/components/org.wso2.carbon.identity.api.user.recovery/src/main/java/org/wso2/carbon/identity/recovery/endpoint/impl/SecurityQuestionsApiServiceImpl.java b/components/org.wso2.carbon.identity.api.user.recovery/src/main/java/org/wso2/carbon/identity/recovery/endpoint/impl/SecurityQuestionsApiServiceImpl.java deleted file mode 100644 index 0928d48d01..0000000000 --- a/components/org.wso2.carbon.identity.api.user.recovery/src/main/java/org/wso2/carbon/identity/recovery/endpoint/impl/SecurityQuestionsApiServiceImpl.java +++ /dev/null @@ -1,90 +0,0 @@ -package org.wso2.carbon.identity.recovery.endpoint.impl; - -import org.apache.commons.lang.ArrayUtils; -import org.apache.commons.lang.StringUtils; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.wso2.carbon.base.MultitenantConstants; -import org.wso2.carbon.identity.application.common.model.User; -import org.wso2.carbon.identity.core.util.IdentityTenantUtil; -import org.wso2.carbon.identity.core.util.IdentityUtil; -import org.wso2.carbon.identity.recovery.IdentityRecoveryClientException; -import org.wso2.carbon.identity.recovery.IdentityRecoveryConstants; -import org.wso2.carbon.identity.recovery.IdentityRecoveryException; -import org.wso2.carbon.identity.recovery.bean.ChallengeQuestionsResponse; -import org.wso2.carbon.identity.recovery.endpoint.Constants; -import org.wso2.carbon.identity.recovery.endpoint.SecurityQuestionsApiService; -import org.wso2.carbon.identity.recovery.endpoint.Utils.RecoveryUtil; -import org.wso2.carbon.identity.recovery.endpoint.dto.InitiateAllQuestionResponseDTO; -import org.wso2.carbon.identity.recovery.password.SecurityQuestionPasswordRecoveryManager; - -import javax.ws.rs.core.Response; - -public class SecurityQuestionsApiServiceImpl extends SecurityQuestionsApiService { - - private static final Log LOG = LogFactory.getLog(SecurityQuestionsApiServiceImpl.class); - - @Override - public Response securityQuestionsGet(String username, String realm, String tenantDomain) { - - if (IdentityUtil.threadLocalProperties.get().get(Constants.TENANT_NAME_FROM_CONTEXT) != null) { - tenantDomain = (String) IdentityUtil.threadLocalProperties.get().get(Constants.TENANT_NAME_FROM_CONTEXT); - } - - User user = new User(); - user.setUserName(username); - - if (StringUtils.isBlank(tenantDomain)) { - user.setTenantDomain(MultitenantConstants.SUPER_TENANT_DOMAIN_NAME); - } else { - user.setTenantDomain(tenantDomain); - } - - int tenantId = IdentityTenantUtil.getTenantId(user.getTenantDomain()); - - if (StringUtils.isBlank(realm)) { - String[] userList = RecoveryUtil.getUserList(tenantId, username); - - if (ArrayUtils.isEmpty(userList)) { - String msg = "Unable to find an user with username: " + username + " in the system."; - LOG.error(msg); - } else if (userList.length == 1) { - user.setUserStoreDomain(IdentityUtil.extractDomainFromName(userList[0])); - } else { - String msg = "There are multiple users with username: " + username + " in the system, " + - "please send the correct user-store domain along with the username."; - LOG.error(msg); - RecoveryUtil.handleBadRequest(msg, Constants.ERROR_CODE_MULTIPLE_USERS_MATCHING); - } - } - - InitiateAllQuestionResponseDTO initiateAllQuestionResponseDTO = null; - - SecurityQuestionPasswordRecoveryManager securityQuestionBasedPwdRecoveryManager = - RecoveryUtil.getSecurityQuestionBasedPwdRecoveryManager(); - try { - ChallengeQuestionsResponse challengeQuestionResponse = securityQuestionBasedPwdRecoveryManager - .initiateUserChallengeQuestionAtOnce(user); - initiateAllQuestionResponseDTO = RecoveryUtil.getInitiateQuestionResponseDTO(challengeQuestionResponse); - - } catch (IdentityRecoveryClientException e) { - if (LOG.isDebugEnabled()) { - LOG.debug("Client Error while initiating password recovery flow at once using security questions ", e); - } - if (IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_CHALLENGE_QUESTION_NOT_FOUND.getCode() - .equals(e.getErrorCode())) { - return Response.noContent().build(); - } - - RecoveryUtil.handleBadRequest(e.getMessage(), e.getErrorCode()); - - } catch (IdentityRecoveryException e) { - RecoveryUtil.handleInternalServerError(Constants.SERVER_ERROR, e.getErrorCode(), LOG, e); - - } catch (Throwable throwable) { - RecoveryUtil.handleInternalServerError(Constants.SERVER_ERROR, IdentityRecoveryConstants - .ErrorMessages.ERROR_CODE_UNEXPECTED.getCode(), LOG, throwable); - } - return Response.ok(initiateAllQuestionResponseDTO).build(); - } -} diff --git a/components/org.wso2.carbon.identity.api.user.recovery/src/main/java/org/wso2/carbon/identity/recovery/endpoint/impl/ValidateAnswerApiServiceImpl.java b/components/org.wso2.carbon.identity.api.user.recovery/src/main/java/org/wso2/carbon/identity/recovery/endpoint/impl/ValidateAnswerApiServiceImpl.java deleted file mode 100644 index f5f025cc86..0000000000 --- a/components/org.wso2.carbon.identity.api.user.recovery/src/main/java/org/wso2/carbon/identity/recovery/endpoint/impl/ValidateAnswerApiServiceImpl.java +++ /dev/null @@ -1,56 +0,0 @@ -package org.wso2.carbon.identity.recovery.endpoint.impl; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.wso2.carbon.identity.recovery.IdentityRecoveryClientException; -import org.wso2.carbon.identity.recovery.IdentityRecoveryConstants; -import org.wso2.carbon.identity.recovery.IdentityRecoveryException; -import org.wso2.carbon.identity.recovery.bean.ChallengeQuestionResponse; -import org.wso2.carbon.identity.recovery.endpoint.*; -import org.wso2.carbon.identity.recovery.endpoint.Utils.RecoveryUtil; - - -import org.wso2.carbon.identity.recovery.endpoint.dto.AnswerVerificationRequestDTO; -import org.wso2.carbon.identity.recovery.endpoint.dto.RetryErrorDTO; - -import org.wso2.carbon.identity.recovery.password.SecurityQuestionPasswordRecoveryManager; - -import javax.ws.rs.core.Response; - -public class ValidateAnswerApiServiceImpl extends ValidateAnswerApiService { - private static final Log LOG = LogFactory.getLog(ValidateAnswerApiServiceImpl.class); - - @Override - public Response validateAnswerPost(AnswerVerificationRequestDTO answerVerificationRequest) { - SecurityQuestionPasswordRecoveryManager securityQuestionBasedPwdRecoveryManager = RecoveryUtil.getSecurityQuestionBasedPwdRecoveryManager(); - ChallengeQuestionResponse challengeQuestion = null; - try { - challengeQuestion = securityQuestionBasedPwdRecoveryManager.validateUserChallengeQuestions - (RecoveryUtil.getUserChallengeAnswers(answerVerificationRequest.getAnswers()), - answerVerificationRequest.getKey(), RecoveryUtil.getProperties(answerVerificationRequest.getProperties())); - } catch (IdentityRecoveryClientException e) { - - if (LOG.isDebugEnabled()) { - LOG.debug("Client Error while verifying challenge answers in recovery flow", e); - } - - if (IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_INVALID_ANSWER_FOR_SECURITY_QUESTION.getCode() - .equals(e.getErrorCode())) { - RetryErrorDTO errorDTO = new RetryErrorDTO(); - errorDTO.setCode(e.getErrorCode()); - errorDTO.setMessage(e.getMessage()); - errorDTO.setDescription(e.getMessage()); - errorDTO.setKey(answerVerificationRequest.getKey()); - return Response.status(Response.Status.PRECONDITION_FAILED).entity(errorDTO).build(); - } - - RecoveryUtil.handleBadRequest(e.getMessage(), e.getErrorCode()); - } catch (IdentityRecoveryException e) { - RecoveryUtil.handleInternalServerError(Constants.SERVER_ERROR, e.getErrorCode(), LOG, e); - } catch (Throwable throwable) { - RecoveryUtil.handleInternalServerError(Constants.SERVER_ERROR, IdentityRecoveryConstants - .ErrorMessages.ERROR_CODE_UNEXPECTED.getCode(), LOG, throwable); - } - return Response.ok(RecoveryUtil.getInitiateQuestionResponseDTO(challengeQuestion)).build(); - } -} diff --git a/components/org.wso2.carbon.identity.api.user.recovery/src/main/resources/META-INF/cxf/user-recovery-v0-9-cxf.xml b/components/org.wso2.carbon.identity.api.user.recovery/src/main/resources/META-INF/cxf/user-recovery-v0-9-cxf.xml index 574bc3e445..c29bb9e75f 100644 --- a/components/org.wso2.carbon.identity.api.user.recovery/src/main/resources/META-INF/cxf/user-recovery-v0-9-cxf.xml +++ b/components/org.wso2.carbon.identity.api.user.recovery/src/main/resources/META-INF/cxf/user-recovery-v0-9-cxf.xml @@ -24,10 +24,7 @@ - - - diff --git a/components/org.wso2.carbon.identity.api.user.recovery/src/main/resources/api.identity.recovery.yaml b/components/org.wso2.carbon.identity.api.user.recovery/src/main/resources/api.identity.recovery.yaml index 770c4c24d8..9582788ea9 100644 --- a/components/org.wso2.carbon.identity.api.user.recovery/src/main/resources/api.identity.recovery.yaml +++ b/components/org.wso2.carbon.identity.api.user.recovery/src/main/resources/api.identity.recovery.yaml @@ -194,164 +194,6 @@ paths: tags: - Password Recovery - - # The endpoint that is used to initiate password reset with security questions. - /security-question: - get: - description: | - This API is used to initiate password recovery using user challenge questions. Response will be a random challenge question with a confirmation key. - x-wso2-request: | - curl -X GET -H "Authorization: Basic YWRtaW46YWRtaW4=" -H "Content-Type: application/json" "https://localhost:9443/api/identity/recovery/v0.9/security-question?username=isura" - - x-wso2-response: | - {"key":"7ced9ef0-7f3f-4f65-a115-ddbcce3a6b49","question":{"question":"City where you were born ?","question-set-id":"http://wso2.org/claims/challengeQuestion1"} - summary: | - Get Challenge Question of User - - # These are the post parameters: - parameters: - - - name: username - in: query - description: username of the user - required: true - type: string - - - name: realm - in: query - description: | - `User Store Domain` that the user belongs to. If not specified, it will be `PRIMARY` domain. - required: false - type: string - - - name: tenant-domain - in: query - description: | - `Tenant Domain` that the user belongs to. If not specified, it will be `carbon.super` domain. - required: false - type: string - - - responses: - 200: - description: Successful response - schema: - $ref: '#/definitions/InitiateQuestionResponse' - 204: - description: No content - 400: - description: Bad Request - schema: - $ref: '#/definitions/Error' - - 500: - description: Server Error - schema: - $ref: '#/definitions/Error' - tags: - - Password Recovery - - Security Question - - # The endpoint that is used to initiate password reset with security questions. - /security-questions: - get: - description: | - This API is used to initiate password recovery using user challenge questions at once. Response will be a random challenge question with a confirmation key. - x-wso2-request: | - curl -X GET -H "Authorization: Basic YWRtaW46YWRtaW4=" -H "Content-Type: application/json" "https://localhost:9443/api/identity/recovery/v0.9/security-question?username=isura" - - x-wso2-response: | - {"key":"f9f04fd7-3666-4bc6-bc99-9190b04b0ccc","questions":[{"question":"City where you were born ?","question-set-id":"http://wso2.org/claims/challengeQuestion1"},{"question":"Model of your first car ?","question-set-id":"http://wso2.org/claims/challengeQuestion2"}],"link":{"rel":"validate-answer","uri":"/api/identity/recovery/v0.9"}} - summary: | - Get Challenge Questions of User - - # These are the post parameters: - parameters: - - - name: username - in: query - description: username of the user - required: true - type: string - - - name: realm - in: query - description: | - `User Store Domain` that the user belongs to. If not specified, it will be `PRIMARY` domain. - required: false - type: string - - - name: tenant-domain - in: query - description: | - `Tenant Domain` that the user belongs to. If not specified, it will be `carbon.super` domain. - required: false - type: string - - - responses: - 200: - description: Successful response - schema: - $ref: '#/definitions/InitiateAllQuestionResponse' - 204: - description: No content - - 400: - description: Bad Request - schema: - $ref: '#/definitions/Error' - - 500: - description: Server Error - schema: - $ref: '#/definitions/Error' - tags: - - Password Recovery - - Security Question - - /validate-answer: - post: - description: | - This is used to validate the user challenge answer. If the user challenge answer is valid, it sends another challenge question to answer until the status becomes `COMPLETE`. If the answer is wrong, user can retry the answer. - x-wso2-request: | - curl -k -X POST -H "Authorization: Basic YWRtaW46YWRtaW4=" -H "Content-Type: application/json" -d '{"key": "0b20bd4d-cd82-4e8f-8ca4-4d265360b56b","answers": [{ "question-set-id": "http://wso2.org/claims/challengeQuestion1","answer": "born"},{"question-set-id": "http://wso2.org/claims/challengeQuestion2","answer": "car"}],"properties": []}' "https://localhost:9443/api/identity/recovery/v0.9/validate-answer" - - - x-wso2-response: | - {"key":"c45d7251-59f1-468d-9844-8a6d7c5fe9d9","question":null,"link":{"rel":"set-password","uri":"/api/identity/recovery/v0.9"}} - summary: | - Validate user challenge answer/answers. - - # These are the post parameters: - parameters: - - - name: AnswerVerificationRequest - in: body - description: User answers verification with key returned in previous step. - required: true - schema: - $ref: '#/definitions/AnswerVerificationRequest' - - responses: - 200: - description: Successful response - schema: - $ref: '#/definitions/InitiateQuestionResponse' - 400: - description: Bad Request - schema: - $ref: '#/definitions/RetryError' - - 500: - description: Server Error - schema: - $ref: '#/definitions/Error' - tags: - - Password Recovery - - Security Question - - /recover-username/: post: description: | @@ -599,32 +441,6 @@ definitions: type: string description: type: string - #----------------------------------------------------- - # The Security Question object - #----------------------------------------------------- - Question: - type: object - properties: - question: - type: string - question-set-id: - type: string - #----------------------------------------------------- - # Security Answers verificiaton request object - #----------------------------------------------------- - AnswerVerificationRequest: - type: object - properties: - key: - type: string - answers: - type: array - items: - $ref: '#/definitions/SecurityAnswer' - properties: - type: array - items: - $ref: '#/definitions/Property' #----------------------------------------------------- # The Error Response object @@ -651,57 +467,6 @@ definitions: value: type: string #----------------------------------------------------- - # Security Answers verificiaton response object - #----------------------------------------------------- - RecoveryInitiatingRequest: - type: object - properties: - user: - $ref: '#/definitions/User' - properties: - type: array - items: - $ref: '#/definitions/Property' - #----------------------------------------------------- - # The InitiateAllQuestionResponse response object - #----------------------------------------------------- - InitiateAllQuestionResponse: - type: object - properties: - key: - type: string - questions: - type: array - items: - $ref: '#/definitions/Question' - link: - $ref: '#/definitions/Link' - - #----------------------------------------------------- - # The InitiateQuestionResponse response object - #----------------------------------------------------- - InitiateQuestionResponse: - type: object - properties: - key: - type: string - question: - $ref: '#/definitions/Question' - link: - $ref: '#/definitions/Link' - - - #----------------------------------------------------- - # User Security Answer object - #----------------------------------------------------- - SecurityAnswer: - type: object - properties: - question-set-id: - type: string - answer: - type: string - #----------------------------------------------------- # Claim object #----------------------------------------------------- Claim: diff --git a/components/org.wso2.carbon.identity.api.user.recovery/src/test/java/org/wso2/carbon/identity/recovery/endpoint/SecurityQuestionApiServiceImplTest.java b/components/org.wso2.carbon.identity.api.user.recovery/src/test/java/org/wso2/carbon/identity/recovery/endpoint/SecurityQuestionApiServiceImplTest.java deleted file mode 100644 index 43f470e822..0000000000 --- a/components/org.wso2.carbon.identity.api.user.recovery/src/test/java/org/wso2/carbon/identity/recovery/endpoint/SecurityQuestionApiServiceImplTest.java +++ /dev/null @@ -1,116 +0,0 @@ -/* - * - * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. - * - * Licensed 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.recovery.endpoint; - -import org.mockito.InjectMocks; -import org.mockito.Mock; -import org.mockito.MockedStatic; -import org.mockito.Mockito; -import org.mockito.MockitoAnnotations; -import org.testng.annotations.AfterMethod; -import org.testng.annotations.BeforeMethod; -import org.testng.annotations.Test; -import org.wso2.carbon.identity.application.common.model.User; -import org.wso2.carbon.identity.core.util.IdentityTenantUtil; -import org.wso2.carbon.identity.core.util.IdentityUtil; -import org.wso2.carbon.identity.recovery.IdentityRecoveryClientException; -import org.wso2.carbon.identity.recovery.IdentityRecoveryConstants; -import org.wso2.carbon.identity.recovery.IdentityRecoveryException; -import org.wso2.carbon.identity.recovery.bean.ChallengeQuestionResponse; -import org.wso2.carbon.identity.recovery.endpoint.Utils.RecoveryUtil; -import org.wso2.carbon.identity.recovery.endpoint.impl.SecurityQuestionApiServiceImpl; -import org.wso2.carbon.identity.recovery.password.SecurityQuestionPasswordRecoveryManager; - -import static org.mockito.Matchers.any; -import static org.mockito.Matchers.anyString; -import static org.testng.Assert.assertEquals; -import static org.testng.Assert.assertNotNull; - -/** - * Unit tests for SecurityQuestionApiServiceImpl.java class - */ -public class SecurityQuestionApiServiceImplTest { - - @Mock - SecurityQuestionPasswordRecoveryManager securityQuestionPasswordRecoveryManager; - - @Mock - ChallengeQuestionResponse challengeQuestionResponse; - - @InjectMocks - SecurityQuestionApiServiceImpl securityQuestionApiService; - - private MockedStatic mockedIdentityUtil; - private MockedStatic mockedRecoveryUtil; - private MockedStatic mockedIdentityTenantUtil; - - @BeforeMethod - public void setUp() { - - MockitoAnnotations.openMocks(this); - mockedIdentityUtil = Mockito.mockStatic(IdentityUtil.class); - mockedRecoveryUtil = Mockito.mockStatic(RecoveryUtil.class); - mockedIdentityTenantUtil = Mockito.mockStatic(IdentityTenantUtil.class); - } - - @AfterMethod - public void tearDown() { - - mockedIdentityUtil.close(); - mockedRecoveryUtil.close(); - mockedIdentityTenantUtil.close(); - } - - @Test - public void testSecurityQuestionGet() { - - mockClasses(); - assertEquals(securityQuestionApiService.securityQuestionGet("admin", null, null).getStatus(), 202); - } - - @Test - public void testIdentityRecoveryClientExceptionforSecurityQuestionGet() throws IdentityRecoveryException { - - mockClasses(); - Mockito.when(securityQuestionPasswordRecoveryManager.initiateUserChallengeQuestion(any(User.class))).thenThrow - (new IdentityRecoveryClientException(IdentityRecoveryConstants.ErrorMessages. - ERROR_CODE_CHALLENGE_QUESTION_NOT_FOUND.getCode(), "")); - assertNotNull(securityQuestionApiService.securityQuestionGet("admin", null, null)); - } - - @Test - public void testIdentityRecoveryExceptionforSecurityQuestionGet() throws IdentityRecoveryException { - - mockClasses(); - Mockito.when(securityQuestionPasswordRecoveryManager.initiateUserChallengeQuestion(any(User.class))).thenThrow - (new IdentityRecoveryException(IdentityRecoveryConstants.ErrorMessages. - ERROR_CODE_CHALLENGE_QUESTION_NOT_FOUND.getCode(), "")); - assertNotNull(securityQuestionApiService.securityQuestionGet("admin", null, null)); - } - - private void mockClasses() { - - mockedIdentityTenantUtil.when(() -> IdentityTenantUtil.getTenantId(anyString())).thenReturn(-1234); - String[] userList = new String[1]; - userList[0] = "admin"; - mockedRecoveryUtil.when(() -> RecoveryUtil.getUserList(-1234, "admin")).thenReturn(userList); - mockedIdentityUtil.when(() -> IdentityUtil.extractDomainFromName(userList[0])).thenReturn("PRIMARY"); - mockedRecoveryUtil.when(RecoveryUtil::getSecurityQuestionBasedPwdRecoveryManager).thenReturn( - securityQuestionPasswordRecoveryManager); - } -} diff --git a/components/org.wso2.carbon.identity.api.user.recovery/src/test/java/org/wso2/carbon/identity/recovery/endpoint/ValidateAnswerApiServiceImplTest.java b/components/org.wso2.carbon.identity.api.user.recovery/src/test/java/org/wso2/carbon/identity/recovery/endpoint/ValidateAnswerApiServiceImplTest.java deleted file mode 100644 index a91ce1045a..0000000000 --- a/components/org.wso2.carbon.identity.api.user.recovery/src/test/java/org/wso2/carbon/identity/recovery/endpoint/ValidateAnswerApiServiceImplTest.java +++ /dev/null @@ -1,159 +0,0 @@ -/* - * - * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. - * - * Licensed 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.recovery.endpoint; - -import org.mockito.InjectMocks; -import org.mockito.Mock; -import org.mockito.MockedStatic; -import org.mockito.Mockito; -import org.mockito.MockitoAnnotations; -import org.testng.annotations.AfterMethod; -import org.testng.annotations.BeforeMethod; -import org.testng.annotations.Test; -import org.wso2.carbon.identity.recovery.IdentityRecoveryClientException; -import org.wso2.carbon.identity.recovery.IdentityRecoveryConstants; -import org.wso2.carbon.identity.recovery.IdentityRecoveryException; -import org.wso2.carbon.identity.recovery.endpoint.Utils.RecoveryUtil; -import org.wso2.carbon.identity.recovery.endpoint.dto.AnswerVerificationRequestDTO; -import org.wso2.carbon.identity.recovery.endpoint.dto.PropertyDTO; -import org.wso2.carbon.identity.recovery.endpoint.dto.SecurityAnswerDTO; -import org.wso2.carbon.identity.recovery.endpoint.impl.ValidateAnswerApiServiceImpl; -import org.wso2.carbon.identity.recovery.model.Property; -import org.wso2.carbon.identity.recovery.model.UserChallengeAnswer; -import org.wso2.carbon.identity.recovery.password.SecurityQuestionPasswordRecoveryManager; - -import java.util.ArrayList; -import java.util.List; - -import static org.mockito.ArgumentMatchers.isNull; -import static org.mockito.Matchers.any; -import static org.mockito.Matchers.anyString; -import static org.testng.Assert.assertEquals; - -/** - * This class contains unit tests for ValidateAnswerApiServiceImpl.java - */ -public class ValidateAnswerApiServiceImplTest { - - @Mock - SecurityQuestionPasswordRecoveryManager securityQuestionPasswordRecoveryManager; - - @InjectMocks - ValidateAnswerApiServiceImpl validateAnswerApiService; - - private AnswerVerificationRequestDTO buildAnswerVerificationRequestDTO() { - - AnswerVerificationRequestDTO answerVerificationRequestDTO = new AnswerVerificationRequestDTO(); - answerVerificationRequestDTO.setKey("DummyKey"); - answerVerificationRequestDTO.setAnswers(buildsecurityAnswerDTOList()); - answerVerificationRequestDTO.setProperties(buildPropertyListDTO()); - return answerVerificationRequestDTO; - } - - private List buildsecurityAnswerDTOList() { - - SecurityAnswerDTO securityAnswerDTO = new SecurityAnswerDTO(); - List securityAnswerDTOList = new ArrayList<>(); - securityAnswerDTO.setQuestionSetId("DummyId"); - securityAnswerDTO.setAnswer("Dummy answer"); - securityAnswerDTOList.add(securityAnswerDTO); - return securityAnswerDTOList; - } - - private List buildPropertyListDTO() { - - PropertyDTO propertyDTO = new PropertyDTO(); - propertyDTO.setKey("DummyPropertyKey"); - propertyDTO.setValue("Dummy property value"); - List propertyDTOList = new ArrayList<>(); - propertyDTOList.add(propertyDTO); - return propertyDTOList; - } - - private MockedStatic mockedRecoveryUtil; - - @BeforeMethod - public void setUp() throws IdentityRecoveryException { - - MockitoAnnotations.openMocks(this); - mockedRecoveryUtil = Mockito.mockStatic(RecoveryUtil.class); - securityQuestionPasswordRecoveryManager = Mockito.mock(SecurityQuestionPasswordRecoveryManager.class); - } - - @AfterMethod - public void tearDown() { - - mockedRecoveryUtil.close(); - } - - @Test - public void testValidateAnswerPost() { - - mockedRecoveryUtil.when(RecoveryUtil::getSecurityQuestionBasedPwdRecoveryManager).thenReturn( - securityQuestionPasswordRecoveryManager); - UserChallengeAnswer[] userChallengeAnswers = new UserChallengeAnswer[1]; - Property[] properties = new Property[1]; - mockedRecoveryUtil.when(() -> RecoveryUtil.getUserChallengeAnswers(buildsecurityAnswerDTOList())).thenReturn( - userChallengeAnswers); - mockedRecoveryUtil.when(() -> RecoveryUtil.getProperties(buildPropertyListDTO())).thenReturn(properties); - assertEquals(validateAnswerApiService.validateAnswerPost(buildAnswerVerificationRequestDTO()).getStatus(), 200); - } - - @Test - public void testIdentityRecoveryClientExceptionwithCodeforValidateAnswerPost() throws IdentityRecoveryException { - - mockedRecoveryUtil.when(RecoveryUtil::getSecurityQuestionBasedPwdRecoveryManager).thenReturn( - securityQuestionPasswordRecoveryManager); - Mockito.when(securityQuestionPasswordRecoveryManager.validateUserChallengeQuestions - (isNull(), anyString(), isNull())).thenThrow - (new IdentityRecoveryClientException(IdentityRecoveryConstants.ErrorMessages. - ERROR_CODE_INVALID_ANSWER_FOR_SECURITY_QUESTION.getCode(), "")); - assertEquals(validateAnswerApiService.validateAnswerPost(buildAnswerVerificationRequestDTO()).getStatus(), 412); - } - - @Test - public void testIdentityRecoveryClientExceptionforValidateAnswerPost() throws IdentityRecoveryException { - - mockedRecoveryUtil.when(RecoveryUtil::getSecurityQuestionBasedPwdRecoveryManager).thenReturn( - securityQuestionPasswordRecoveryManager); - Mockito.when(securityQuestionPasswordRecoveryManager.validateUserChallengeQuestions - (any(UserChallengeAnswer[].class), anyString(), any(Property[].class))).thenThrow - (new IdentityRecoveryClientException(IdentityRecoveryConstants.ErrorMessages. - ERROR_CODE_INVALID_ANSWER_FOR_SECURITY_QUESTION.toString(), "")); - assertEquals(validateAnswerApiService.validateAnswerPost(buildAnswerVerificationRequestDTO()).getStatus(), 200); - } - - @Test - public void testIdentityRecoveryExceptionforValidateAnswerPost() throws IdentityRecoveryException { - - mockedRecoveryUtil.when(RecoveryUtil::getSecurityQuestionBasedPwdRecoveryManager).thenReturn( - securityQuestionPasswordRecoveryManager); - Mockito.when(securityQuestionPasswordRecoveryManager.validateUserChallengeQuestions - (any(UserChallengeAnswer[].class), anyString(), any(Property[].class))).thenThrow - (new IdentityRecoveryException("")); - assertEquals(validateAnswerApiService.validateAnswerPost(buildAnswerVerificationRequestDTO()).getStatus(), 200); - } - - @Test - public void testThrowableforValidateAnswerPost() throws IdentityRecoveryException { - - mockedRecoveryUtil.when(RecoveryUtil::getSecurityQuestionBasedPwdRecoveryManager).thenReturn( - securityQuestionPasswordRecoveryManager); - assertEquals(validateAnswerApiService.validateAnswerPost(null).getStatus(), 200); - } -} diff --git a/components/org.wso2.carbon.identity.api.user.recovery/src/test/resources/testng.xml b/components/org.wso2.carbon.identity.api.user.recovery/src/test/resources/testng.xml index fcc6d35770..a81e47881a 100644 --- a/components/org.wso2.carbon.identity.api.user.recovery/src/test/resources/testng.xml +++ b/components/org.wso2.carbon.identity.api.user.recovery/src/test/resources/testng.xml @@ -21,8 +21,6 @@ - - diff --git a/components/org.wso2.carbon.identity.recovery.ui/pom.xml b/components/org.wso2.carbon.identity.recovery.ui/pom.xml deleted file mode 100644 index 9aff7af256..0000000000 --- a/components/org.wso2.carbon.identity.recovery.ui/pom.xml +++ /dev/null @@ -1,102 +0,0 @@ - - - - - identity-governance - org.wso2.carbon.identity.governance - 1.8.85-SNAPSHOT - ../../pom.xml - - - 4.0.0 - org.wso2.carbon.identity.recovery.ui - bundle - WSO2 Carbon - Identity Recovery Management UI - - - - org.apache.axis2.wso2 - axis2 - - - org.apache.ws.commons.axiom.wso2 - axiom - - - org.wso2.carbon - org.wso2.carbon.ui - - - org.ops4j.pax.logging - pax-logging-api - - - org.wso2.orbit.org.owasp.encoder - encoder - - - org.wso2.carbon.identity.framework - org.wso2.carbon.identity.core - - - org.wso2.carbon.identity.framework - org.wso2.carbon.identity.core.ui - - - org.wso2.carbon.identity.governance - org.wso2.carbon.identity.recovery.stub - ${project.version} - - - org.apache.felix - org.apache.felix.scr.ds-annotations - provided - - - - - - - org.apache.felix - maven-bundle-plugin - true - - - - ${project.artifactId} - - - org.wso2.carbon.identity.recovery.ui.*;version"${identity.governance.exp.pkg.version}" - - - org.wso2.carbon.identity.recovery.stub;version="${identity.governance.imp.pkg.version.range}" - - * - UIBundle - - - - - com.github.spotbugs - spotbugs-maven-plugin - - Medium - - - - - diff --git a/components/org.wso2.carbon.identity.recovery.ui/src/main/java/org/wso2/carbon/identity/recovery/ui/IdentityManagementAdminClient.java b/components/org.wso2.carbon.identity.recovery.ui/src/main/java/org/wso2/carbon/identity/recovery/ui/IdentityManagementAdminClient.java deleted file mode 100644 index 371a5bd334..0000000000 --- a/components/org.wso2.carbon.identity.recovery.ui/src/main/java/org/wso2/carbon/identity/recovery/ui/IdentityManagementAdminClient.java +++ /dev/null @@ -1,138 +0,0 @@ -/* - * - * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. - * - * WSO2 Inc. 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.recovery.ui; - -import org.apache.axis2.AxisFault; -import org.apache.axis2.client.Options; -import org.apache.axis2.client.ServiceClient; -import org.apache.axis2.context.ConfigurationContext; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.wso2.carbon.identity.application.common.model.xsd.User; -import org.wso2.carbon.identity.recovery.stub.ChallengeQuestionManagementAdminServiceStub; -import org.wso2.carbon.identity.recovery.stub.model.ChallengeQuestion; -import org.wso2.carbon.identity.recovery.stub.model.UserChallengeAnswer; - - -/** - * Admin service client for ChallengeQuestionManagement Service. - * - */ -public class IdentityManagementAdminClient { - - public static final String CHALLENGE_QUESTION = "challenge.question"; - public static final String CHALLENGE_QUESTION_UPDATE = "challenge.question.update"; - public static final String CHALLENGE_QUESTION_DELETE = "challenge.question.delete"; - public static final String CHALLENGE_QUESTION_SET_TEMP = "challenge.question.set.temp"; - - - private static final Log log = LogFactory.getLog(IdentityManagementAdminClient.class); - private static final String SERVICE_NAME = "ChallengeQuestionManagementAdminService"; - private ChallengeQuestionManagementAdminServiceStub stub = null; - - public IdentityManagementAdminClient(String cookie, String url, ConfigurationContext configContext) - throws Exception { - try { - stub = new ChallengeQuestionManagementAdminServiceStub(configContext, url + SERVICE_NAME); - ServiceClient client = stub._getServiceClient(); - Options option = client.getOptions(); - option.setManageSession(true); - option.setProperty(org.apache.axis2.transport.http.HTTPConstants.COOKIE_STRING, cookie); - } catch (Exception e) { - handleException(e.getMessage(), e); - } - } - - public ChallengeQuestion[] getChallengeQuestionsForTenant(String tenantDomain) throws AxisFault { - - try { - return stub.getChallengeQuestionsOfTenant(tenantDomain); - } catch (Exception e) { - handleException(e.getMessage(), e); - } - return new ChallengeQuestion[0]; - } - - - public ChallengeQuestion[] getChallengeQuestionsForUser(User user) throws AxisFault { - - try { - return stub.getChallengeQuestionsForUser(user); - } catch (Exception e) { - handleException(e.getMessage(), e); - } - - return new ChallengeQuestion[0]; - } - - public ChallengeQuestion[] getChallengeQuestionsForLocale(String tenantDomain, String locale) throws AxisFault { - - try { - return stub.getChallengeQuestionsForLocale(tenantDomain, locale); - } catch (Exception e) { - handleException(e.getMessage(), e); - } - - return new ChallengeQuestion[0]; - } - - - public void setChallengeQuestions(ChallengeQuestion[] challengeQuestions, String tenantDomain) - throws AxisFault { - try { - stub.setChallengeQuestionsOfTenant(challengeQuestions, tenantDomain); - } catch (Exception e) { - handleException(e.getMessage(), e); - } - } - - public void deleteChallengeQuestions(ChallengeQuestion[] challengeQuestions, String tenantDomain) - throws AxisFault { - try { - stub.deleteChallengeQuestionsOfTenant(challengeQuestions, tenantDomain); - } catch (Exception e) { - handleException(e.getMessage(), e); - } - } - - public void setUserChallengeAnswers(User user, UserChallengeAnswer[] userChallengeAnswers) - throws AxisFault { - try { - stub.setUserChallengeAnswers(user, userChallengeAnswers); - } catch (Exception e) { - handleException(e.getMessage(), e); - } - } - - public UserChallengeAnswer[] getUserChallengeAnswers(User user) throws AxisFault { - try { - return stub.getUserChallengeAnswers(user); - } catch (Exception e) { - handleException(e.getMessage(), e); - } - - return new UserChallengeAnswer[0]; - } - - private String[] handleException(String msg, Exception e) throws AxisFault { - log.error(msg, e); - throw new AxisFault(msg, e); - } -} diff --git a/components/org.wso2.carbon.identity.recovery.ui/src/main/java/org/wso2/carbon/identity/recovery/ui/Utils.java b/components/org.wso2.carbon.identity.recovery.ui/src/main/java/org/wso2/carbon/identity/recovery/ui/Utils.java deleted file mode 100644 index 424b199109..0000000000 --- a/components/org.wso2.carbon.identity.recovery.ui/src/main/java/org/wso2/carbon/identity/recovery/ui/Utils.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. - * - * Licensed 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.recovery.ui; - -import org.apache.commons.lang.ArrayUtils; -import org.apache.commons.lang.StringUtils; -import org.wso2.carbon.identity.recovery.stub.model.ChallengeQuestion; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; -import java.util.HashSet; -import java.util.List; -import java.util.Locale; - -/** - * Helper class for Challenge questions admin service client - */ -public class Utils { - - public static final String DEFAULT_LOCALE = "en_US"; - public static final String WSO2_CLAIM_DIALECT = "http://wso2.org/claims/"; - - private Utils() { - } - - public static String getLocaleString(Locale locale) { - String languageCode = locale.getLanguage(); - String countryCode = locale.getCountry(); - if (StringUtils.isBlank(countryCode)) { - countryCode = languageCode; - } - - return languageCode + "_" + countryCode; - } - - public static Comparator questionComparator = new Comparator() { - public int compare(ChallengeQuestion q1, ChallengeQuestion q2) { - String stringQ1 = q1.getQuestionId() + q1.getLocale(); - String stringQ2 = q2.getQuestionId() + q2.getLocale(); - //ascending order - return stringQ1.compareTo(stringQ2); - } - }; - - public static List getChallengeSetUris(ChallengeQuestion[] challengeQuestions) { - HashSet questionSetNames = new HashSet(); - if (ArrayUtils.isNotEmpty(challengeQuestions)) { - for (ChallengeQuestion question : challengeQuestions) { - if (question.getQuestionSetId() != null) { - questionSetNames.add(question.getQuestionSetId()); - } - } - } - List challengeSetUriList = new ArrayList(questionSetNames); - Collections.sort(challengeSetUriList); - return challengeSetUriList; - } - - public static List getUniqueQuestionIds(List challengeQuestions, String setId) { - HashSet questionIds = new HashSet(); - for (ChallengeQuestion question : challengeQuestions) { - if (StringUtils.equalsIgnoreCase(setId, question.getQuestionSetId())) { - questionIds.add(question.getQuestionId()); - } - } - List questioIdList = new ArrayList<>(questionIds); - Collections.sort(questioIdList); - return questioIdList; - } -} \ No newline at end of file diff --git a/components/org.wso2.carbon.identity.recovery.ui/src/main/resources/META-INF/component.xml b/components/org.wso2.carbon.identity.recovery.ui/src/main/resources/META-INF/component.xml deleted file mode 100644 index 4af8ab7570..0000000000 --- a/components/org.wso2.carbon.identity.recovery.ui/src/main/resources/META-INF/component.xml +++ /dev/null @@ -1,66 +0,0 @@ - - - - - - - - - - - - - identity_security_questions - manage.challenge.questions - org.wso2.carbon.identity.recovery.ui.i18n.Resources - manage_menu - # - region1 - 3 - manage - ../recovery-mgt/images/keys.gif - /permission/admin - false - - - identity_security_questions_add - challenge.questions.add - org.wso2.carbon.identity.recovery.ui.i18n.Resources - identity_security_questions - ../recovery-mgt/challenges-mgt-add.jsp - region1 - 1 - manage - ../recovery-mgt/images/add.gif - /permission/admin/manage - false - - - identity_security_questions_List - challenge.questions.list - org.wso2.carbon.identity.recovery.ui.i18n.Resources - identity_security_questions - ../recovery-mgt/challenge-set-list.jsp - region1 - 2 - manage - ../recovery-mgt/images/list.gif - /permission/admin/manage - false - - - diff --git a/components/org.wso2.carbon.identity.recovery.ui/src/main/resources/org/wso2/carbon/identity/recovery/ui/i18n/Resources.properties b/components/org.wso2.carbon.identity.recovery.ui/src/main/resources/org/wso2/carbon/identity/recovery/ui/i18n/Resources.properties deleted file mode 100644 index 0d1d482847..0000000000 --- a/components/org.wso2.carbon.identity.recovery.ui/src/main/resources/org/wso2/carbon/identity/recovery/ui/i18n/Resources.properties +++ /dev/null @@ -1,48 +0,0 @@ -# -# -# Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. -# -# WSO2 Inc. 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. -# -# -# -# -manage.challenge.questions=Challenge Questions -challenge.questions.add=Add -challenge.questions.list=List -edit=Edit -delete=Delete -challenge.set.question.add=Add New Question Set / Question -challenge.set.add=Add Challenge Question Set -challenge.set.add.details=Add Challenge Question Set Details -challenge.question.add=Add Challenge Question -challenge.add=Add Challenge Questions -challenge.questions.mgt=Challenge Question Management -confirm.delete.challenge.set=Do you want to delete the challenge question set -confirm.delete.challenge.question=Do you want to delete the selected challenge question -challenge.set.none=No challenge question sets registered. -challenge.question.set=Challenge Question Sets -challenge.question.add.questionSet=Challenge Question Set Id -challenge.question.add.locale.mapping=Add Locale Mapping to a question -challenge.question.add.question=Add Challenge Question -challenge.question.add.questionId=Challenge Question Id -challenge.question.add.questionLocale=Challenge Question Locale -challenge.question.questionId=Question_ID -challenge.question.questionLocale=Locale -challenge.question.question=Challenge Questions -challenge.question.actions=Actions -challenge.question=Challenge Question : -account.id.recovery=We need some information from you to recover your account Id - diff --git a/components/org.wso2.carbon.identity.recovery.ui/src/main/resources/web/recovery-mgt/challenge-question-add.jsp b/components/org.wso2.carbon.identity.recovery.ui/src/main/resources/web/recovery-mgt/challenge-question-add.jsp deleted file mode 100644 index 0e388990c4..0000000000 --- a/components/org.wso2.carbon.identity.recovery.ui/src/main/resources/web/recovery-mgt/challenge-question-add.jsp +++ /dev/null @@ -1,620 +0,0 @@ -<%-- - ~ Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. - ~ - ~ Licensed 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. - --%> - -<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %> -<%@ taglib uri="http://wso2.org/projects/carbon/taglibs/carbontags.jar" prefix="carbon" %> -<%@ page import="org.apache.axis2.context.ConfigurationContext" %> -<%@page import="org.apache.commons.lang.ArrayUtils" %> - -<%@page import="org.apache.commons.lang.StringUtils" %> - - - -<%@ page import="org.owasp.encoder.Encode" %> -<%@ page import="org.wso2.carbon.CarbonConstants" %> -<%@ page import="org.wso2.carbon.context.CarbonContext" %> -<%@ page import="org.wso2.carbon.identity.core.util.IdentityUtil" %> -<%@ page import="org.wso2.carbon.identity.recovery.stub.model.ChallengeQuestion" %> -<%@ page import="org.wso2.carbon.identity.recovery.ui.IdentityManagementAdminClient" %> -<%@ page import="org.wso2.carbon.identity.recovery.ui.Utils" %> -<%@ page import="org.wso2.carbon.ui.CarbonUIMessage" %> -<%@ page import="org.wso2.carbon.ui.CarbonUIUtil" %> -<%@ page import="org.wso2.carbon.utils.ServerConstants" %> -<%@ page import="java.util.ArrayList" %> -<%@ page import="java.util.Arrays" %> -<%@ page import="java.util.Collections" %> -<%@ page import="java.util.List" %> -<%@ page import="java.util.Locale" %> - - -<% - - List updatedChallenges; - List deletedChallenges; - List tempChallenges; - List challenges; - List challengeURIs; - - // add/edit/delete within the set - String deleteRowId = request.getParameter("deleteRowId"); - String editRowId = request.getParameter("editRowId"); - String addRowId = request.getParameter("addRowId"); - - String updateRowId = request.getParameter("updateRowId"); - String updatedQuestion = request.getParameter("updatedQuestion"); - - - String setName = request.getParameter("setName"); - String question = request.getParameter("question"); - String questionId = request.getParameter("questionId"); - String questionLocale = request.getParameter("questionLocale"); - - String localeMapping = request.getParameter("localeMapping"); - - challenges = (List) session.getAttribute(IdentityManagementAdminClient.CHALLENGE_QUESTION); - tempChallenges = (List) session.getAttribute(IdentityManagementAdminClient.CHALLENGE_QUESTION_SET_TEMP); - deletedChallenges = (List) session.getAttribute(IdentityManagementAdminClient.CHALLENGE_QUESTION_DELETE); - updatedChallenges = (List) session.getAttribute(IdentityManagementAdminClient.CHALLENGE_QUESTION_UPDATE); - - try { - String cookie = (String) session - .getAttribute(ServerConstants.ADMIN_SERVICE_COOKIE); - String backendServerURL = CarbonUIUtil.getServerURL(config.getServletContext(), - session); - ConfigurationContext configContext = (ConfigurationContext) config - .getServletContext() - .getAttribute(CarbonConstants.CONFIGURATION_CONTEXT); - IdentityManagementAdminClient client = - new IdentityManagementAdminClient(cookie, backendServerURL, configContext); - - String tenantDomain = CarbonContext.getThreadLocalCarbonContext().getTenantDomain(); - ChallengeQuestion[] challengeQuestionsForUser = client.getChallengeQuestionsForTenant(tenantDomain); - - challengeURIs = Utils.getChallengeSetUris(challengeQuestionsForUser); - // retrieve challenge questions for user. - if (ArrayUtils.isNotEmpty(challengeQuestionsForUser)) { - challenges = new ArrayList(Arrays.asList(challengeQuestionsForUser)); - session.setAttribute(IdentityManagementAdminClient.CHALLENGE_QUESTION, challenges); - } - - } catch (Exception e) { - CarbonUIMessage.sendCarbonUIMessage(e.getMessage(), CarbonUIMessage.ERROR, - request); -%> - -<% - return; - } - - - if (deletedChallenges == null) { - deletedChallenges = new ArrayList(); - } - - if (updatedChallenges == null) { - updatedChallenges = new ArrayList(); - } - - if (challenges == null) { - challenges = new ArrayList(); - } - - if (tempChallenges != null) { - // delete questions - if (deleteRowId != null) { - int rowNo = Integer.parseInt(deleteRowId); - ChallengeQuestion removed = tempChallenges.remove(rowNo); - updatedChallenges.remove(rowNo); - deletedChallenges.add(removed); - } - - // edited questions - if (updateRowId != null) { - int rowNo = Integer.parseInt(updateRowId); - ChallengeQuestion selected = tempChallenges.get(rowNo); - if (StringUtils.isNotBlank(updatedQuestion)) { - selected.setQuestion(updatedQuestion); - updatedChallenges.get(rowNo).setQuestion(updatedQuestion); - } - } - - } else { - tempChallenges = new ArrayList(); - } - - // adding new questions - if (addRowId != null) { - ChallengeQuestion dto = new ChallengeQuestion(); - dto.setQuestion(addRowId); - dto.setQuestionSetId(setName); - dto.setQuestionId(questionId); - dto.setLocale(questionLocale); - tempChallenges.add(dto); - updatedChallenges.add(dto); - } - - session.setAttribute(IdentityManagementAdminClient.CHALLENGE_QUESTION_DELETE, deletedChallenges); - session.setAttribute(IdentityManagementAdminClient.CHALLENGE_QUESTION_UPDATE, updatedChallenges); - - Collections.sort(tempChallenges, Utils.questionComparator); - Collections.sort(challenges, Utils.questionComparator); - - session.setAttribute(IdentityManagementAdminClient.CHALLENGE_QUESTION_SET_TEMP, tempChallenges); - session.setAttribute(IdentityManagementAdminClient.CHALLENGE_QUESTION, challenges); -%> - - - - - - -
-

- -
-
- - - - -
- - - - - - - - - - - - - - - - - - - - - - - -
- - * - - -
- - * - - Yes - No - - <% if (StringUtils.isNotBlank(localeMapping) && StringUtils.equalsIgnoreCase("yes", localeMapping)) {%> - - <% - } else { - %> - - <%}%> - -
- - * - - <% if (StringUtils.isBlank(localeMapping) || StringUtils.equalsIgnoreCase("no", localeMapping)) {%> - - <%} else {%> - - - <%}%> -
- - * - - -
- - * - - <% if (StringUtils.isNotBlank(question)) { %> - - <%} else { %> - - <% }%> -
- -
-
- - -

 

- <% if (!updatedChallenges.isEmpty()) { %> - - - - - - - - - - -
- - - - - - - - - - <% - if (updatedChallenges.size() > 0) { - for (int i = 0; i < updatedChallenges.size(); i++) { - ChallengeQuestion tempQuestion = updatedChallenges.get(i); - if (StringUtils.isNotBlank(setName) && StringUtils.equalsIgnoreCase(tempQuestion.getQuestionSetId(), setName)) { - - %> - - - <% if (IdentityUtil.isNotBlank(editRowId) && (Integer.parseInt(editRowId) == i)) {%> - - <% - } else { - %> - - <% - }%> - - - - - - <% - } - } - } - %> - - -
<%=Encode.forHtmlContent(tempQuestion.getQuestionId())%> - <%=Encode.forHtmlContent(tempQuestion.getQuestion())%> - - <%=Encode.forHtmlContent(tempQuestion.getQuestion())%> - <%=Encode.forHtmlContent(tempQuestion.getLocale())%> - - <% - if (IdentityUtil.isNotBlank(editRowId) && (Integer.parseInt(editRowId) == i)) { - %> - - Update - - <% - } else { %> - - Edit - - <%}%> - - Delete - -
-
- - -
- <%}%> - - -

 

-

 

-

 

- - - - - - - -
- - - - - - - - - <% - if (challenges.size() > 0) { - for (ChallengeQuestion challengeQuestion : challenges) { - if (StringUtils.isNotBlank(setName) && StringUtils.equalsIgnoreCase(challengeQuestion.getQuestionSetId(), setName)) { - - %> - - - - - - - <% - } - } - } - %> - - -
<%=Encode.forHtmlContent(challengeQuestion.getQuestionId())%> - <%=Encode.forHtmlContent(challengeQuestion.getQuestion())%> - <%=Encode.forHtmlContent(challengeQuestion.getLocale())%> -
-
- -
-
-
-
- diff --git a/components/org.wso2.carbon.identity.recovery.ui/src/main/resources/web/recovery-mgt/challenge-set-add.jsp b/components/org.wso2.carbon.identity.recovery.ui/src/main/resources/web/recovery-mgt/challenge-set-add.jsp deleted file mode 100644 index fda52356ac..0000000000 --- a/components/org.wso2.carbon.identity.recovery.ui/src/main/resources/web/recovery-mgt/challenge-set-add.jsp +++ /dev/null @@ -1,188 +0,0 @@ -<%-- - ~ Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. - ~ - ~ Licensed 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. - --%> - -<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %> -<%@ taglib uri="http://wso2.org/projects/carbon/taglibs/carbontags.jar" prefix="carbon" %> -<%@ page import="org.apache.axis2.context.ConfigurationContext" %> -<%@page import="org.owasp.encoder.Encode" %> -<%@page import="org.wso2.carbon.CarbonConstants" %> - - - -<%@ page import="org.wso2.carbon.context.CarbonContext" %> -<%@ page import="org.wso2.carbon.identity.recovery.stub.model.ChallengeQuestion" %> -<%@ page import="org.wso2.carbon.identity.recovery.ui.IdentityManagementAdminClient" %> -<%@ page import="org.wso2.carbon.identity.recovery.ui.Utils" %> -<%@ page import="org.wso2.carbon.ui.CarbonUIMessage" %> -<%@ page import="org.wso2.carbon.ui.CarbonUIUtil" %> -<%@ page import="org.wso2.carbon.utils.ServerConstants" %> -<%@ page import="java.util.List" %> -<%@ page import="java.util.Locale" %> - - -<% - try { - String cookie = (String) session - .getAttribute(ServerConstants.ADMIN_SERVICE_COOKIE); - String backendServerURL = CarbonUIUtil.getServerURL(config.getServletContext(), - session); - ConfigurationContext configContext = (ConfigurationContext) config - .getServletContext() - .getAttribute(CarbonConstants.CONFIGURATION_CONTEXT); - IdentityManagementAdminClient client = - new IdentityManagementAdminClient(cookie, backendServerURL, configContext); - - String tenantDomain = CarbonContext.getThreadLocalCarbonContext().getTenantDomain(); - ChallengeQuestion[] challengeQuestionsForTenant = client.getChallengeQuestionsForTenant(tenantDomain); - - List challengeSetUris = Utils.getChallengeSetUris(challengeQuestionsForTenant); - - } catch (Exception e) { - CarbonUIMessage.sendCarbonUIMessage(e.getMessage(), CarbonUIMessage.ERROR, - request); -%> - -<% - return; - } - - -%> - - - - - - -
-

- -
-
- - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - -
- - * - - -
- - * - -
- - * - - -
- - * - - -
- - -
-
-
-
-
-
- diff --git a/components/org.wso2.carbon.identity.recovery.ui/src/main/resources/web/recovery-mgt/challenge-set-list.jsp b/components/org.wso2.carbon.identity.recovery.ui/src/main/resources/web/recovery-mgt/challenge-set-list.jsp deleted file mode 100644 index 2358825964..0000000000 --- a/components/org.wso2.carbon.identity.recovery.ui/src/main/resources/web/recovery-mgt/challenge-set-list.jsp +++ /dev/null @@ -1,159 +0,0 @@ -<%-- - ~ Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. - ~ - ~ Licensed 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. - --%> - - -<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %> -<%@ taglib uri="http://wso2.org/projects/carbon/taglibs/carbontags.jar" prefix="carbon" %> -<%@ page import="org.apache.axis2.context.ConfigurationContext" %> -<%@page import="org.owasp.encoder.Encode" %> -<%@page import="org.wso2.carbon.CarbonConstants" %> - - - -<%@ page import="org.wso2.carbon.context.CarbonContext" %> -<%@ page import="org.wso2.carbon.identity.recovery.stub.model.ChallengeQuestion" %> -<%@ page import="org.wso2.carbon.identity.recovery.ui.IdentityManagementAdminClient" %> -<%@ page import="org.wso2.carbon.identity.recovery.ui.Utils" %> -<%@ page import="org.wso2.carbon.ui.CarbonUIMessage" %> -<%@ page import="org.wso2.carbon.ui.CarbonUIUtil" %> -<%@ page import="org.wso2.carbon.utils.ServerConstants" %> -<%@ page import="java.util.Collections" %> -<%@ page import="java.util.List" %> - - -<% - session.removeAttribute(IdentityManagementAdminClient.CHALLENGE_QUESTION); - session.removeAttribute(IdentityManagementAdminClient.CHALLENGE_QUESTION_DELETE); - session.removeAttribute(IdentityManagementAdminClient.CHALLENGE_QUESTION_UPDATE); - List challenges = null; - List questionSetNamesList = null; - - try { - String cookie = (String) session - .getAttribute(ServerConstants.ADMIN_SERVICE_COOKIE); - String backendServerURL = CarbonUIUtil.getServerURL(config.getServletContext(), - session); - ConfigurationContext configContext = (ConfigurationContext) config - .getServletContext() - .getAttribute(CarbonConstants.CONFIGURATION_CONTEXT); - IdentityManagementAdminClient client = - new IdentityManagementAdminClient(cookie, backendServerURL, configContext); - - - String tenantDomain = CarbonContext.getThreadLocalCarbonContext().getTenantDomain(); - // retrieve all available challenge questions for user's tenant and locale. - ChallengeQuestion[] challengeQuestions = client.getChallengeQuestionsForTenant(tenantDomain); - questionSetNamesList = Utils.getChallengeSetUris(challengeQuestions); - Collections.sort(questionSetNamesList); - - } catch (Exception e) { - CarbonUIMessage.sendCarbonUIMessage(e.getMessage(), CarbonUIMessage.ERROR, request); -%> - -<% - return; - } - - -%> - - - - - - -
-

-
- <%----%> - <%----%> - <%----%> - <%----%> - <%--
- <%--class="icon-link">Add new challenge questions set
--%> - -

 

- - - - - - - - <% if (questionSetNamesList.size() > 0) { - for (String questionSetName : questionSetNamesList) { - %> - - - - - - <% - } - } else { - %> - - - - <% - } - %> - -
- <%=Encode.forHtmlContent(questionSetName)%> - - - - - - - -
- -
-
-
-
diff --git a/components/org.wso2.carbon.identity.recovery.ui/src/main/resources/web/recovery-mgt/challenges-mgt-add.jsp b/components/org.wso2.carbon.identity.recovery.ui/src/main/resources/web/recovery-mgt/challenges-mgt-add.jsp deleted file mode 100644 index 8646aa9f68..0000000000 --- a/components/org.wso2.carbon.identity.recovery.ui/src/main/resources/web/recovery-mgt/challenges-mgt-add.jsp +++ /dev/null @@ -1,112 +0,0 @@ -<%-- - ~ Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. - ~ - ~ Licensed 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. - --%> - - -<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %> -<%@ taglib uri="http://wso2.org/projects/carbon/taglibs/carbontags.jar" prefix="carbon" %> -<%@ page import="org.apache.axis2.context.ConfigurationContext" %> -<%@page import="org.apache.commons.lang.StringUtils" %> - -<%@page import="org.wso2.carbon.CarbonConstants" %> - - - -<%@ page import="org.wso2.carbon.context.CarbonContext" %> -<%@ page import="org.wso2.carbon.identity.recovery.stub.model.ChallengeQuestion" %> -<%@ page import="org.wso2.carbon.identity.recovery.ui.IdentityManagementAdminClient" %> -<%@ page import="org.wso2.carbon.ui.CarbonUIMessage" %> -<%@ page import="org.wso2.carbon.ui.CarbonUIUtil" %> -<%@ page import="org.wso2.carbon.utils.ServerConstants" %> -<%@ page import="java.util.ArrayList" %> - - -<% - // clear the questions that were meant to be updated or deleted. - String clear = request.getParameter("clear"); - if (StringUtils.isNotBlank(clear)) { - session.setAttribute(IdentityManagementAdminClient.CHALLENGE_QUESTION_DELETE, new ArrayList()); - session.setAttribute(IdentityManagementAdminClient.CHALLENGE_QUESTION_UPDATE, new ArrayList()); - } - - try { - String cookie = (String) session - .getAttribute(ServerConstants.ADMIN_SERVICE_COOKIE); - String backendServerURL = CarbonUIUtil.getServerURL(config.getServletContext(), - session); - ConfigurationContext configContext = (ConfigurationContext) config - .getServletContext() - .getAttribute(CarbonConstants.CONFIGURATION_CONTEXT); - IdentityManagementAdminClient client = - new IdentityManagementAdminClient(cookie, backendServerURL, configContext); - - String tenantDomain = CarbonContext.getThreadLocalCarbonContext().getTenantDomain(); - ChallengeQuestion[] allChallengeQuestions = client.getChallengeQuestionsForTenant(tenantDomain); - - } catch (Exception e) { - CarbonUIMessage.sendCarbonUIMessage(e.getMessage(), CarbonUIMessage.ERROR, request); -%> - -<% - return; - - } -%> - - - - - -
-

- -
- - - - - - - - -
-
- - - -
-
-
- - - -
-
- -
-
-
-
- - diff --git a/components/org.wso2.carbon.identity.recovery.ui/src/main/resources/web/recovery-mgt/challenges-mgt-finish-ajaxprocessor.jsp b/components/org.wso2.carbon.identity.recovery.ui/src/main/resources/web/recovery-mgt/challenges-mgt-finish-ajaxprocessor.jsp deleted file mode 100644 index 6edc5379bd..0000000000 --- a/components/org.wso2.carbon.identity.recovery.ui/src/main/resources/web/recovery-mgt/challenges-mgt-finish-ajaxprocessor.jsp +++ /dev/null @@ -1,153 +0,0 @@ -<%-- - ~ Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. - ~ - ~ Licensed 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. - --%> - -<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %> -<%@ taglib uri="http://wso2.org/projects/carbon/taglibs/carbontags.jar" prefix="carbon" %> - - -<%@page import="org.apache.axis2.context.ConfigurationContext" %> -<%@page import="org.apache.commons.collections.CollectionUtils" %> -<%@ page import="org.apache.commons.lang.StringUtils" %> -<%@ page import="org.wso2.carbon.CarbonConstants" %> -<%@ page import="org.wso2.carbon.context.CarbonContext" %> -<%@ page import="org.wso2.carbon.identity.recovery.stub.model.ChallengeQuestion" %> -<%@ page import="org.wso2.carbon.identity.recovery.ui.IdentityManagementAdminClient" %> -<%@ page import="org.wso2.carbon.identity.recovery.ui.Utils" %> -<%@ page import="org.wso2.carbon.ui.CarbonUIMessage" %> -<%@ page import="org.wso2.carbon.ui.CarbonUIUtil" %> -<%@ page import="org.wso2.carbon.utils.ServerConstants" %> -<%@ page import="java.util.ArrayList" %> -<%@ page import="java.util.Arrays" %> -<%@ page import="java.util.Collections" %> -<%@ page import="java.util.List" %> - -<% - String httpMethod = request.getMethod(); - if (!"post".equalsIgnoreCase(httpMethod)) { - response.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED); - return; - } - - String removeSetId = request.getParameter("removeSetId"); - - // params coming from a request to create a new question set - String setId = request.getParameter("setName"); - String questionId = request.getParameter("questionId0"); - String question = request.getParameter("question0"); - String questionLocale = request.getParameter("questionLocale0"); - - - // flags to identity whether questions are to be deleted or updated at the backend. - boolean deleteQuestions = false; - boolean updateQuestions = false; - - List questionToBeDeleted = new ArrayList(); - List questionToBeUpdated = new ArrayList(); - List retrievedQuestions = null; - - Object toBeDeleted = session.getAttribute(IdentityManagementAdminClient.CHALLENGE_QUESTION_DELETE); - if (toBeDeleted != null) { - questionToBeDeleted = (List) toBeDeleted; - } - - Object toBeUpdated = session.getAttribute(IdentityManagementAdminClient.CHALLENGE_QUESTION_UPDATE); - if (toBeUpdated != null) { - questionToBeUpdated = (List) toBeUpdated; - } - - try { - String cookie = (String) session - .getAttribute(ServerConstants.ADMIN_SERVICE_COOKIE); - String backendServerURL = CarbonUIUtil.getServerURL(config.getServletContext(), - session); - ConfigurationContext configContext = (ConfigurationContext) config - .getServletContext() - .getAttribute(CarbonConstants.CONFIGURATION_CONTEXT); - IdentityManagementAdminClient proxy = - new IdentityManagementAdminClient(cookie, backendServerURL, configContext); - - String tenantDomain = CarbonContext.getThreadLocalCarbonContext().getTenantDomain(); - - - ChallengeQuestion[] retrievedChallengeQuestions = proxy.getChallengeQuestionsForTenant(tenantDomain); - if (retrievedChallengeQuestions != null) { - retrievedQuestions = Arrays.asList(retrievedChallengeQuestions); - } else { - retrievedQuestions = Collections.emptyList(); - } - - if (removeSetId != null && removeSetId.trim().length() > 0) { - for (ChallengeQuestion challengeQuestion : retrievedQuestions) { - if (StringUtils.equals(challengeQuestion.getQuestionSetId(), removeSetId)) { - questionToBeDeleted.add(challengeQuestion); - } - } - } - - // create a new questions set along with its first question. - if (StringUtils.isNotBlank(setId) && StringUtils.isNotBlank(questionId) && StringUtils.isNotBlank(question) && - StringUtils.isNotBlank(questionLocale)) { - ChallengeQuestion challengeQuestion = new ChallengeQuestion(); - - if (!setId.startsWith(Utils.WSO2_CLAIM_DIALECT)) { - setId = Utils.WSO2_CLAIM_DIALECT + setId; - } - challengeQuestion.setQuestionSetId(setId); - challengeQuestion.setQuestionId(questionId); - challengeQuestion.setQuestion(question); - challengeQuestion.setLocale(questionLocale); - - questionToBeUpdated.add(challengeQuestion); - } - - if (CollectionUtils.isNotEmpty(questionToBeUpdated)) { - updateQuestions = true; - } - - if (CollectionUtils.isNotEmpty(questionToBeDeleted)) { - deleteQuestions = true; - } - - if (deleteQuestions) { - int size = questionToBeDeleted.size(); - // call admin client to delete the questions. - proxy.deleteChallengeQuestions( - questionToBeDeleted.toArray(new ChallengeQuestion[size]), tenantDomain); - session.setAttribute(IdentityManagementAdminClient.CHALLENGE_QUESTION_DELETE, new ArrayList()); - } - - if (updateQuestions) { - int size = questionToBeUpdated.size(); - proxy.setChallengeQuestions(questionToBeUpdated.toArray(new ChallengeQuestion[size]), tenantDomain); - session.setAttribute(IdentityManagementAdminClient.CHALLENGE_QUESTION_DELETE, new ArrayList()); - } -%> - -<% -} catch (Exception e) { - CarbonUIMessage.sendCarbonUIMessage(e.getMessage(), CarbonUIMessage.ERROR, request); -%> - -<% - return; - } -%> - - diff --git a/components/org.wso2.carbon.identity.recovery.ui/src/main/resources/web/recovery-mgt/challenges-mgt.jsp b/components/org.wso2.carbon.identity.recovery.ui/src/main/resources/web/recovery-mgt/challenges-mgt.jsp deleted file mode 100644 index 25344156ea..0000000000 --- a/components/org.wso2.carbon.identity.recovery.ui/src/main/resources/web/recovery-mgt/challenges-mgt.jsp +++ /dev/null @@ -1,302 +0,0 @@ -<%-- - ~ Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. - ~ - ~ Licensed 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. - --%> - - -<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %> -<%@ taglib uri="http://wso2.org/projects/carbon/taglibs/carbontags.jar" prefix="carbon" %> -<%@ page import="org.apache.axis2.context.ConfigurationContext" %> -<%@page import="org.apache.commons.lang.ArrayUtils" %> - -<%@page import="org.apache.commons.lang.StringUtils" %> - - - -<%@ page import="org.owasp.encoder.Encode" %> -<%@ page import="org.wso2.carbon.CarbonConstants" %> -<%@ page import="org.wso2.carbon.context.CarbonContext" %> -<%@ page import="org.wso2.carbon.identity.core.util.IdentityUtil" %> -<%@ page import="org.wso2.carbon.identity.recovery.stub.model.ChallengeQuestion" %> -<%@ page import="org.wso2.carbon.identity.recovery.ui.IdentityManagementAdminClient" %> -<%@ page import="org.wso2.carbon.identity.recovery.ui.Utils" %> -<%@ page import="org.wso2.carbon.ui.CarbonUIMessage" %> -<%@ page import="org.wso2.carbon.ui.CarbonUIUtil" %> -<%@ page import="org.wso2.carbon.utils.ServerConstants" %> -<%@ page import="java.util.ArrayList" %> -<%@ page import="java.util.Arrays" %> -<%@ page import="java.util.Collections" %> -<%@ page import="java.util.List" %> - - -<% - - List updatedChallenges; - List deletedChallenges; - List challenges; - String deleteRowId = request.getParameter("deleteRowId"); - String editRowId = request.getParameter("editRowId"); - String updateRowId = request.getParameter("updateRowId"); - String updatedQuestion = request.getParameter("updatedQuestion"); - - String clear = request.getParameter("clear"); - - String addRowId = request.getParameter("addRowId"); - String setName = request.getParameter("setName"); - String questionId = request.getParameter("questionId"); - String questionLocale = request.getParameter("questionLocale"); - - challenges = (List) session.getAttribute(IdentityManagementAdminClient.CHALLENGE_QUESTION); - deletedChallenges = (List) session.getAttribute(IdentityManagementAdminClient.CHALLENGE_QUESTION_DELETE); - updatedChallenges = (List) session.getAttribute(IdentityManagementAdminClient.CHALLENGE_QUESTION_UPDATE); - - if (challenges == null) { - try { - String cookie = (String) session - .getAttribute(ServerConstants.ADMIN_SERVICE_COOKIE); - String backendServerURL = CarbonUIUtil.getServerURL(config.getServletContext(), - session); - ConfigurationContext configContext = (ConfigurationContext) config - .getServletContext() - .getAttribute(CarbonConstants.CONFIGURATION_CONTEXT); - IdentityManagementAdminClient client = - new IdentityManagementAdminClient(cookie, backendServerURL, configContext); - - String tenantDomain = CarbonContext.getThreadLocalCarbonContext().getTenantDomain(); - ChallengeQuestion[] challengeQuestionsForUser = client.getChallengeQuestionsForTenant(tenantDomain); - - // retrieve challenge questions for user. - if (ArrayUtils.isNotEmpty(challengeQuestionsForUser)) { - challenges = new ArrayList(Arrays.asList(challengeQuestionsForUser)); - session.setAttribute(IdentityManagementAdminClient.CHALLENGE_QUESTION, challenges); - } - } catch (Exception e) { - CarbonUIMessage.sendCarbonUIMessage(e.getMessage(), CarbonUIMessage.ERROR, - request); -%> - -<% - return; - } - } - - if (deletedChallenges == null || StringUtils.isNotBlank(clear)) { - deletedChallenges = new ArrayList(); - } - - if (updatedChallenges == null || StringUtils.isNotBlank(clear)) { - updatedChallenges = new ArrayList(); - } - - if (challenges != null) { - // delete questions - if (deleteRowId != null) { - int rowNo = Integer.parseInt(deleteRowId); - ChallengeQuestion removed = challenges.remove(rowNo); - deletedChallenges.add(removed); - } - - // edited questions - if (updateRowId != null) { - int rowNo = Integer.parseInt(updateRowId); - ChallengeQuestion selected = challenges.get(rowNo); - if (StringUtils.isNotBlank(updatedQuestion)) { - selected.setQuestion(updatedQuestion); - } - updatedChallenges.add(selected); - } - - } else { - challenges = new ArrayList(); - } - - // adding new questions - if (addRowId != null) { - ChallengeQuestion dto = new ChallengeQuestion(); - dto.setQuestion(addRowId); - dto.setQuestionSetId(setName); - dto.setQuestionId(questionId); - dto.setLocale(questionLocale); - challenges.add(dto); - updatedChallenges.add(dto); - } - - session.setAttribute(IdentityManagementAdminClient.CHALLENGE_QUESTION_DELETE, deletedChallenges); - session.setAttribute(IdentityManagementAdminClient.CHALLENGE_QUESTION_UPDATE, updatedChallenges); - - Collections.sort(challenges, Utils.questionComparator); - session.setAttribute(IdentityManagementAdminClient.CHALLENGE_QUESTION, challenges); -%> - - - - - - -
-

- -
-
- - - - -
-
- - - -
-
- - -

 

- - - - - - - - - - -
- - - - - - - - - - <% - if (challenges.size() > 0) { - for (int i = 0; i < challenges.size(); i++) { - ChallengeQuestion question = challenges.get(i); - if (StringUtils.isNotBlank(setName) && StringUtils.equalsIgnoreCase(question.getQuestionSetId(), setName)) { - - %> - - - <% if (IdentityUtil.isNotBlank(editRowId) && (Integer.parseInt(editRowId) == i)) {%> - - <% - } else { - %> - - <% - }%> - - - - - - <% - } - } - } - %> - - -
<%=Encode.forHtmlContent(question.getQuestionId())%> - - <%=Encode.forHtmlContent(question.getQuestion())%> - - <%=Encode.forHtmlContent(question.getQuestion())%> - <%=Encode.forHtmlContent(question.getLocale())%> - - <% - if (IdentityUtil.isNotBlank(editRowId) && (Integer.parseInt(editRowId) == i)) { - %> - - Update - - <% - } else { %> - - Edit - - <%}%> - - Delete - -
-
- - -
- - -
-
-
-
- diff --git a/components/org.wso2.carbon.identity.recovery.ui/src/main/resources/web/recovery-mgt/images/add.gif b/components/org.wso2.carbon.identity.recovery.ui/src/main/resources/web/recovery-mgt/images/add.gif deleted file mode 100644 index 4bfdd7983e..0000000000 Binary files a/components/org.wso2.carbon.identity.recovery.ui/src/main/resources/web/recovery-mgt/images/add.gif and /dev/null differ diff --git a/components/org.wso2.carbon.identity.recovery.ui/src/main/resources/web/recovery-mgt/images/delete.gif b/components/org.wso2.carbon.identity.recovery.ui/src/main/resources/web/recovery-mgt/images/delete.gif deleted file mode 100644 index 471f55c15f..0000000000 Binary files a/components/org.wso2.carbon.identity.recovery.ui/src/main/resources/web/recovery-mgt/images/delete.gif and /dev/null differ diff --git a/components/org.wso2.carbon.identity.recovery.ui/src/main/resources/web/recovery-mgt/images/edit.gif b/components/org.wso2.carbon.identity.recovery.ui/src/main/resources/web/recovery-mgt/images/edit.gif deleted file mode 100644 index 90bd4dce69..0000000000 Binary files a/components/org.wso2.carbon.identity.recovery.ui/src/main/resources/web/recovery-mgt/images/edit.gif and /dev/null differ diff --git a/components/org.wso2.carbon.identity.recovery.ui/src/main/resources/web/recovery-mgt/images/keys.gif b/components/org.wso2.carbon.identity.recovery.ui/src/main/resources/web/recovery-mgt/images/keys.gif deleted file mode 100644 index 08612cbfd6..0000000000 Binary files a/components/org.wso2.carbon.identity.recovery.ui/src/main/resources/web/recovery-mgt/images/keys.gif and /dev/null differ diff --git a/components/org.wso2.carbon.identity.recovery.ui/src/main/resources/web/recovery-mgt/images/list.gif b/components/org.wso2.carbon.identity.recovery.ui/src/main/resources/web/recovery-mgt/images/list.gif deleted file mode 100644 index 638d8ab6ea..0000000000 Binary files a/components/org.wso2.carbon.identity.recovery.ui/src/main/resources/web/recovery-mgt/images/list.gif and /dev/null differ diff --git a/components/org.wso2.carbon.identity.recovery/src/main/java/org/wso2/carbon/identity/recovery/ChallengeQuestionManager.java b/components/org.wso2.carbon.identity.recovery/src/main/java/org/wso2/carbon/identity/recovery/ChallengeQuestionManager.java deleted file mode 100644 index adf55c9495..0000000000 --- a/components/org.wso2.carbon.identity.recovery/src/main/java/org/wso2/carbon/identity/recovery/ChallengeQuestionManager.java +++ /dev/null @@ -1,1207 +0,0 @@ -/* - * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. - * - * WSO2 Inc. 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.recovery; - -import org.apache.commons.collections.MapUtils; -import org.apache.commons.lang.ArrayUtils; -import org.apache.commons.lang.StringUtils; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.wso2.carbon.context.CarbonContext; -import org.wso2.carbon.identity.application.common.model.User; -import org.wso2.carbon.identity.base.IdentityException; -import org.wso2.carbon.identity.base.IdentityRuntimeException; -import org.wso2.carbon.identity.core.persistence.registry.RegistryResourceMgtService; -import org.wso2.carbon.identity.core.util.IdentityUtil; -import org.wso2.carbon.identity.event.IdentityEventClientException; -import org.wso2.carbon.identity.event.IdentityEventConstants; -import org.wso2.carbon.identity.event.IdentityEventException; -import org.wso2.carbon.identity.event.IdentityEventServerException; -import org.wso2.carbon.identity.event.event.Event; -import org.wso2.carbon.identity.recovery.internal.IdentityRecoveryServiceDataHolder; -import org.wso2.carbon.identity.recovery.model.ChallengeQuestion; -import org.wso2.carbon.identity.recovery.model.UserChallengeAnswer; -import org.wso2.carbon.identity.recovery.util.Utils; -import org.wso2.carbon.registry.core.Collection; -import org.wso2.carbon.registry.core.CollectionImpl; -import org.wso2.carbon.registry.core.RegistryConstants; -import org.wso2.carbon.registry.core.Resource; -import org.wso2.carbon.registry.core.ResourceImpl; -import org.wso2.carbon.registry.core.exceptions.RegistryException; -import org.wso2.carbon.user.api.UserStoreException; -import org.wso2.carbon.user.core.UserStoreManager; -import org.wso2.carbon.utils.multitenancy.MultitenantConstants; -import org.wso2.carbon.utils.multitenancy.MultitenantUtils; - -import java.io.UnsupportedEncodingException; -import java.nio.charset.Charset; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import static org.wso2.carbon.identity.recovery.IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_CHALLENG_ANSWER_MISSING; -import static org.wso2.carbon.identity.recovery.IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_ERROR_DELETING_CHALLENGE_SET; -import static org.wso2.carbon.identity.recovery.IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_INVALID_CHALLENGE_QUESTION_VALUE; -import static org.wso2.carbon.identity.recovery.IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_REMOVING_CHALLENGE_QUESTIONS; -import static org.wso2.carbon.identity.recovery.IdentityRecoveryConstants.LOCALE_EN_US; - -/** - * OSGi Service to handle functionality related to challenge question management and verification. - */ -public class ChallengeQuestionManager { - - private static final Log log = LogFactory.getLog(ChallengeQuestionManager.class); - private static ChallengeQuestionManager instance = new ChallengeQuestionManager(); - - private ChallengeQuestionManager() { - - } - - public static ChallengeQuestionManager getInstance() { - return instance; - } - - private IdentityRecoveryServiceDataHolder dataHolder = IdentityRecoveryServiceDataHolder.getInstance(); - private RegistryResourceMgtService resourceMgtService = dataHolder.getResourceMgtService(); - - private static final String QUESTIONS_BASE_PATH = IdentityRecoveryConstants.IDENTITY_MANAGEMENT_QUESTIONS; - - - /** - * Get all challenge questions registered for a tenant. - * - * @param tenantDomain - * @return - * @throws IdentityRecoveryServerException - */ - public List getAllChallengeQuestions(String tenantDomain) throws IdentityRecoveryServerException { - - tenantDomain = validateTenantDomain(tenantDomain); - List challengeQuestions = new ArrayList<>(); - - try { - Resource questionCollection = resourceMgtService.getIdentityResource(QUESTIONS_BASE_PATH, tenantDomain); - if (questionCollection != null) { - Collection questionSetCollection = (Collection) resourceMgtService.getIdentityResource( - QUESTIONS_BASE_PATH, tenantDomain); - - for (String questionSetId : questionSetCollection.getChildren()) { - Collection questionIdCollection = - (Collection) resourceMgtService.getIdentityResource(questionSetId, tenantDomain); - // iterate each question to find the one with correct locale - for (String questionIdPath : questionIdCollection.getChildren()) { - Collection questions = - (Collection) resourceMgtService.getIdentityResource(questionIdPath, tenantDomain); - for (String question : questions.getChildren()) { - Resource resource = resourceMgtService.getIdentityResource(question, tenantDomain); - if (resource != null) { - challengeQuestions.add(createChallengeQuestion(resource)); - } - } - - } - } - } - return challengeQuestions; - } catch (RegistryException e) { - throw Utils.handleServerException(IdentityRecoveryConstants.ErrorMessages - .ERROR_CODE_REGISTRY_EXCEPTION_GET_CHALLENGE_QUESTIONS, null, e); - } - - } - - - /** - * Get registered challenge questions in tenant based on a locale. - * - * @param tenantDomain - * @param locale - * @return - * @throws IdentityRecoveryException - */ - public List getAllChallengeQuestions(String tenantDomain, String locale) - throws IdentityRecoveryException { - // check the value and set defaults if empty or null - locale = validateLocale(locale); - tenantDomain = validateTenantDomain(tenantDomain); - - List questions = new ArrayList<>(); - try { - Resource questionCollection = resourceMgtService.getIdentityResource(QUESTIONS_BASE_PATH, tenantDomain); - // check whether the base challenge question directory exists - if (questionCollection != null) { - Collection questionSetCollection = (Collection) resourceMgtService.getIdentityResource( - QUESTIONS_BASE_PATH, tenantDomain); - - for (String questionSetId : questionSetCollection.getChildren()) { - Collection questionIdCollection = (Collection) resourceMgtService. - getIdentityResource(questionSetId, tenantDomain); - // iterate each question to find the one with correct locale - for (String questionIdPath : questionIdCollection.getChildren()) { - Resource questionResource = resourceMgtService.getIdentityResource(questionIdPath, - tenantDomain, locale); - if (questionResource != null) { - questions.add(createChallengeQuestion(questionResource)); - } - } - } - } - - } catch (RegistryException e) { - throw Utils.handleServerException(IdentityRecoveryConstants.ErrorMessages - .ERROR_CODE_REGISTRY_EXCEPTION_GET_CHALLENGE_QUESTIONS, null, e); - } - - return questions; - } - - /** - * Get all challenge questions set URIs registered for a tenant. - * - * @param tenantDomain - * @return - * @throws IdentityRecoveryServerException - */ - public List getAllChallengeQuestionSetsURIs(String tenantDomain) throws - IdentityRecoveryServerException { - - tenantDomain = validateTenantDomain(tenantDomain); - List challengeQuestions = new ArrayList<>(); - - try { - Resource questionCollection = resourceMgtService.getIdentityResource(QUESTIONS_BASE_PATH, tenantDomain); - if (questionCollection != null) { - Collection questionSetCollection = (Collection) resourceMgtService.getIdentityResource( - QUESTIONS_BASE_PATH, tenantDomain); - - for (String questionSetId : questionSetCollection.getChildren()) { - challengeQuestions.add(questionSetId.replace(QUESTIONS_BASE_PATH, IdentityRecoveryConstants - .WSO2CARBON_CLAIM_DIALECT)); - } - } - return challengeQuestions; - } catch (RegistryException e) { - throw Utils.handleServerException(IdentityRecoveryConstants.ErrorMessages - .ERROR_CODE_REGISTRY_EXCEPTION_GET_CHALLENGE_QUESTIONS, null, e); - } - - } - - /** - * Get challenge questions available for a user. - * - * @param tenantDomain tenantDomain of the user - * @param user User object - * @return List of available challenge questions in user's locale in the tenantDomain. If no challenge questions - * are available we return challenge questions from the default en_US locale. - * @throws IdentityRecoveryException - */ - public List getAllChallengeQuestionsForUser(String tenantDomain, - User user) throws IdentityRecoveryException { - - // Identify the locale of the user - String locale = getLocaleOfUser(user, tenantDomain); - // get challenge questions in the given tenant domain for give locale. - List challengeQuestions = getAllChallengeQuestions(tenantDomain, locale); - - /* - If there are no challenge questions found in the locale of the user and the locale is not the default one. - we return challenge questions from default en_US locale. - */ - if (challengeQuestions.isEmpty() && !StringUtils.equalsIgnoreCase(LOCALE_EN_US, locale)) { - String error = "No challenge questions available in '%s' locale in %s tenant. Sending questions of " + - "default '%s' locale"; - log.error(String.format(error, locale, tenantDomain, LOCALE_EN_US)); - challengeQuestions = getAllChallengeQuestions(tenantDomain, LOCALE_EN_US); - } - - return challengeQuestions; - } - - - /** - * Set default challenge questions to a tenant registry. (This is done during startup) - * - * @param tenantDomain - * @throws IdentityRecoveryException - */ - public void setDefaultChallengeQuestions(String tenantDomain) throws IdentityRecoveryException { - - tenantDomain = validateTenantDomain(tenantDomain); - - // check whether we already have default questions. - boolean isDefaultAvailable = !getAllChallengeQuestions(tenantDomain).isEmpty(); - if (isDefaultAvailable) { - if (log.isDebugEnabled()) { - log.debug("Default Challenge Questions already available."); - } - return; - } - - ChallengeQuestion[] questions = Utils.getDefaultChallengeQuestions(); - addChallengeQuestions(questions, tenantDomain); - - if (log.isDebugEnabled()) { - String errorMsg = "%d default challenge questions added to registry of %s tenant."; - log.debug(String.format(errorMsg, questions.length, tenantDomain)); - } - } - - /** - * Add new challenge questions to the registry of a tenant - * - * @param questions - * @param tenantDomain - * @throws IdentityRecoveryException - */ - public void addChallengeQuestions(ChallengeQuestion[] questions, String tenantDomain) throws IdentityRecoveryException { - try { - tenantDomain = validateTenantDomain(tenantDomain); - - // check whether registry path for question collection exists - Resource challengeQuestionCollection = - resourceMgtService.getIdentityResource(QUESTIONS_BASE_PATH, tenantDomain); - - // create the question collection if it does not exist - if (challengeQuestionCollection == null) { - challengeQuestionCollection = new CollectionImpl(); - resourceMgtService. - putIdentityResource(challengeQuestionCollection, QUESTIONS_BASE_PATH, tenantDomain); - } - - for (ChallengeQuestion challengeQuestion : questions) { - validateChallengeQuestionAttributes(challengeQuestion); - - String questionPath = getQuestionPath(challengeQuestion); - String locale = validateLocale(challengeQuestion.getLocale()); - - // create a registry resource - Resource resource = createRegistryResource(challengeQuestion); - resourceMgtService.putIdentityResource(resource, questionPath, tenantDomain, locale); - } - - } catch (RegistryException | UnsupportedEncodingException e) { - throw Utils.handleServerException(IdentityRecoveryConstants.ErrorMessages - .ERROR_CODE_REGISTRY_EXCEPTION_SET_CHALLENGE_QUESTIONS, null, e); - } - - } - - - /** - * Delete challenge questions from a tenant registry. - * - * @param challengeQuestions - * @param tenantDomain - * @throws IdentityRecoveryException - */ - public void deleteChallengeQuestions(ChallengeQuestion[] challengeQuestions, String tenantDomain) - throws IdentityRecoveryException { - try { - tenantDomain = validateTenantDomain(tenantDomain); - - for (ChallengeQuestion question : challengeQuestions) { - if (isChallengeQuestionExists(question, tenantDomain)) { - String questionPath = getQuestionPath(question); - if (StringUtils.isNotEmpty(question.getLocale())) { - String locale = question.getLocale(); - resourceMgtService.deleteIdentityResource(questionPath, tenantDomain, locale); - } else { - resourceMgtService.deleteIdentityResource(questionPath, tenantDomain); - } - } - } - } catch (IdentityRuntimeException e) { - log.error("Error deleting challenge quesitons in " + tenantDomain); - throw new IdentityRecoveryException("Error when deleting challenge questions.", e); - } - } - - /** - * Delete challenge question set from a tenant registry. - * - * @param challengeQuestionUri - * @param locale - * @param tenantDomain - * @throws IdentityRecoveryException - */ - public void deleteChallengeQuestionSet(String challengeQuestionUri, String locale, String tenantDomain) - throws IdentityRecoveryException { - try { - tenantDomain = validateTenantDomain(tenantDomain); - if (isChallengeQuestionSetExists(challengeQuestionUri, tenantDomain)) { - String questionSetPath = getQuestionSetPath(challengeQuestionUri); - if (StringUtils.isEmpty(locale)) { - resourceMgtService.deleteIdentityResource(questionSetPath, tenantDomain); - } else { - deleteChallengeQuestionsByLocale(questionSetPath, tenantDomain, locale); - } - } - } catch (IdentityRuntimeException e) { - log.error("Error deleting challenge set in " + tenantDomain); - throw Utils.handleServerException(ERROR_CODE_ERROR_DELETING_CHALLENGE_SET, challengeQuestionUri, e); - } - } - - /** - * - * @param questionSetPath - * @param tenantDomain - * @param locale - */ - private void deleteChallengeQuestionsByLocale(String questionSetPath, String tenantDomain, String locale) throws IdentityRecoveryServerException { - - try { - Collection questionIdCollection = (Collection) resourceMgtService.getIdentityResource - (getQuestionSetPath(questionSetPath), tenantDomain); - // iterate each question to find the one with correct locale - for (String questionIdPath : questionIdCollection.getChildren()) { - Resource questionResource = resourceMgtService.getIdentityResource(questionIdPath, - tenantDomain, locale); - if (questionResource != null) { - resourceMgtService.deleteIdentityResource(questionIdPath, tenantDomain, locale); - } - } - - } catch (RegistryException e) { - throw Utils.handleServerException(IdentityRecoveryConstants.ErrorMessages - .ERROR_CODE_REGISTRY_EXCEPTION_DELETE_CHALLENGE_QUESTIONS, locale, e); - } - - } - - /** - * Get challenge questions answered by a user. - * - * @param user - * @return - */ - public UserChallengeAnswer[] getChallengeAnswersOfUser(User user) throws IdentityRecoveryException { - - validateUser(user); - - List userChallengeAnswers = new ArrayList<>(); - if (log.isDebugEnabled()) { - log.debug("Retrieving Challenge question from the user profile."); - } - - List challengesUris = getChallengeQuestionUris(user); - for (String challengesUri1 : challengesUris) { - String challengesUri = challengesUri1.trim(); - String challengeValue; - try { - challengeValue = Utils.getClaimFromUserStoreManager(user, challengesUri); - } catch (UserStoreException e) { - throw Utils.handleServerException(IdentityRecoveryConstants.ErrorMessages - .ERROR_CODE_GETTING_CHALLENGE_QUESTIONS, user.getUserName(), e); - } - - String challengeQuestionSeparator = getChallengeSeparator(); - - String[] challengeValues = challengeValue.split(challengeQuestionSeparator); - if (challengeValues != null && challengeValues.length == 2) { - ChallengeQuestion userChallengeQuestion = new ChallengeQuestion(challengesUri, - challengeValues[0].trim()); - UserChallengeAnswer userChallengeAnswer = new UserChallengeAnswer(userChallengeQuestion, - challengeValues[1].trim()); - userChallengeAnswers.add(userChallengeAnswer); - } - } - - if (!userChallengeAnswers.isEmpty()) { - return userChallengeAnswers.toArray(new UserChallengeAnswer[userChallengeAnswers.size()]); - } else { - return new UserChallengeAnswer[0]; - } - } - - /** - * Retrieve the challenge question answered from a particular challenge question set. - * - * @param user - * @param challengesUri claim uri of the challenge set - * @return - * @throws IdentityRecoveryException - */ - public ChallengeQuestion getUserChallengeQuestion(User user, String challengesUri) throws IdentityRecoveryException { - - validateUser(user); - - ChallengeQuestion userChallengeQuestion = null; - if (log.isDebugEnabled()) { - log.debug("Retrieving Challenge question from the user profile."); - } - - String challengeValue = null; - try { - challengeValue = Utils.getClaimFromUserStoreManager(user, challengesUri); - } catch (UserStoreException e) { - throw Utils.handleServerException(IdentityRecoveryConstants.ErrorMessages - .ERROR_CODE_GETTING_CHALLENGE_QUESTION, user.getUserName(), e); - } - - if (challengeValue != null) { - - String challengeQuestionSeparator = getChallengeSeparator(); - - String[] challengeValues = challengeValue.split(challengeQuestionSeparator); - if (challengeValues != null && challengeValues.length == 2) { - userChallengeQuestion = new ChallengeQuestion(challengesUri, challengeValues[0].trim()); - } - } - return userChallengeQuestion; - - } - - public String[] getUserChallengeQuestionIds(User user) - throws IdentityRecoveryException { - - validateUser(user); - - if (log.isDebugEnabled()) { - log.debug("Retrieving answered Challenge question set ids from the user profile."); - } - List challengesUris = getChallengeQuestionUris(user); - - if (challengesUris.isEmpty()) { - String msg = "No associated challenge question found for the user : " + user.getUserName(); - if (log.isDebugEnabled()) { - log.debug(msg); - } - return new String[0]; - } - String[] urls = new String[challengesUris.size()]; - return challengesUris.toArray(urls); - - } - - /** - * Get the claims URIs of the challenge sets answered by the user - * - * @param user - * @return - */ - public List getChallengeQuestionUris(User user) throws IdentityRecoveryException { - - validateUser(user); - - if (log.isDebugEnabled()) { - String msg = String.format("Getting answered challenge question uris from %s's profile.", user.toString()); - log.debug(msg); - } - - List challenges = new ArrayList(); - String claimValue = null; - String[] challengesUris; - - try { - claimValue = Utils.getClaimFromUserStoreManager(user, IdentityRecoveryConstants.CHALLENGE_QUESTION_URI); - } catch (UserStoreException e) { - throw Utils.handleServerException(IdentityRecoveryConstants.ErrorMessages - .ERROR_CODE_GETTING_CHALLENGE_URIS, user.getUserName(), e); - } - - if (claimValue != null) { - - String challengeQuestionSeparator = getChallengeSeparator(); - - if (claimValue.contains(challengeQuestionSeparator)) { - challengesUris = claimValue.split(challengeQuestionSeparator); - } else { - challengesUris = new String[]{claimValue.trim()}; - } - - for (String challengesUri : challengesUris) { - if (StringUtils.isNotBlank(challengesUri)) { - challenges.add(challengesUri.trim()); - } - } - } - - return challenges; - } - - /** - * Get the existing answers for the challenge questions. - * - * @param user User - * @param userChallengeAnswers List of UserChallengeAnswer objects - * @return Existing challenge questions and answers. - */ - private Map retrieveAnsweredChallenges(User user, UserChallengeAnswer[] userChallengeAnswers) - throws IdentityRecoveryException { - - Map existingQuestionAndAnswers = new HashMap<>(); - if (ArrayUtils.isNotEmpty(userChallengeAnswers)) { - List claimsList = new ArrayList<>(); - for (UserChallengeAnswer answer : userChallengeAnswers) { - if (answer != null && answer.getQuestion() != null - && StringUtils.isNotBlank(answer.getQuestion().getQuestionSetId())) { - claimsList.add(answer.getQuestion().getQuestionSetId().trim()); - } - } - existingQuestionAndAnswers = Utils.getClaimListOfUser(user, claimsList.toArray(new String[0])); - } - if (log.isDebugEnabled()) { - if (MapUtils.isEmpty(existingQuestionAndAnswers)) { - log.debug("No previous questions set for the user: " + user.getUserName()); - } - } - return existingQuestionAndAnswers; - } - - /** - * @param user - * @param userChallengeAnswers - * @throws IdentityException - */ - public void setChallengesOfUser(User user, UserChallengeAnswer[] userChallengeAnswers) throws IdentityRecoveryException { - - validateUser(user); - if (log.isDebugEnabled()) { - log.debug(String.format("Setting user challenge question answers in %s's profile.", user.toString())); - } - - try { - String tenantDomain = StringUtils.isBlank(user.getTenantDomain()) ? - MultitenantConstants.SUPER_TENANT_DOMAIN_NAME : user.getTenantDomain(); - - // validate whether two questions from the same set has been answered. - validateSecurityQuestionDuplicate(userChallengeAnswers); - - // check whether the answered questions exist in the tenant domain - checkChallengeQuestionExists(userChallengeAnswers, tenantDomain); - - // Get the existing challenge questions and answers for the user. - Map existingQuestionAndAnswers = retrieveAnsweredChallenges(user, userChallengeAnswers); - - triggerChallengeAnswersValidation(user, userChallengeAnswers, - existingQuestionAndAnswers, IdentityEventConstants.Event.PRE_SET_CHALLENGE_QUESTION_ANSWERS); - - List challengesUris = new ArrayList(); - String challengesUrisValue = ""; - String separator = getChallengeSeparator(); - - Map challengeQuestionToUpdate = new HashMap<>(); - - if (!ArrayUtils.isEmpty(userChallengeAnswers)) { - for (UserChallengeAnswer userChallengeAnswer : userChallengeAnswers) { - - if (StringUtils.isNotBlank(userChallengeAnswer.getQuestion().getQuestionSetId()) && - StringUtils.isNotBlank(userChallengeAnswer.getQuestion().getQuestion()) && - StringUtils.isNotBlank(userChallengeAnswer.getAnswer())) { - - // Get the previous answer for the question. - String oldValue = existingQuestionAndAnswers - .get(userChallengeAnswer.getQuestion().getQuestionSetId().trim()); - - if (oldValue != null && oldValue.contains(separator)) { - String oldAnswer = oldValue.split(separator)[1]; - if (!oldAnswer.trim().equals(userChallengeAnswer.getAnswer().trim())) { - String claimValue = userChallengeAnswer.getQuestion().getQuestion().trim() + separator + - Utils.doHash(userChallengeAnswer.getAnswer().trim().toLowerCase()); - challengeQuestionToUpdate - .put(userChallengeAnswer.getQuestion().getQuestionSetId().trim(), claimValue); - } - } else { - String claimValue = userChallengeAnswer.getQuestion().getQuestion().trim() + separator + - Utils.doHash(userChallengeAnswer.getAnswer().trim().toLowerCase()); - challengeQuestionToUpdate - .put(userChallengeAnswer.getQuestion().getQuestionSetId().trim(), claimValue); - } - challengesUris.add(userChallengeAnswer.getQuestion().getQuestionSetId().trim()); - } - } - - for (String challengesUri : challengesUris) { - if ("".equals(challengesUrisValue)) { - challengesUrisValue = challengesUri; - } else { - challengesUrisValue = challengesUrisValue + - separator + challengesUri; - } - } - challengeQuestionToUpdate.put(IdentityRecoveryConstants.CHALLENGE_QUESTION_URI, challengesUrisValue); - if (MapUtils.isNotEmpty(challengeQuestionToUpdate)) { - Utils.setClaimsListOfUser(user, challengeQuestionToUpdate); - } - triggerChallengeAnswersValidation(user, userChallengeAnswers, - existingQuestionAndAnswers, IdentityEventConstants.Event.POST_SET_CHALLENGE_QUESTION_ANSWERS); - } - } catch (org.wso2.carbon.user.api.UserStoreException e) { - throw Utils.handleServerException( - ERROR_CODE_REMOVING_CHALLENGE_QUESTIONS, user.getUserName(), e); - } - } - - /** - * Trigger challenge question answers validation according to the given event name. - * - * @param user User - * @param userChallengeAnswers Array of challenge answers - * @param eventName Event name - * @throws IdentityRecoveryClientException Error while validating the challenge answers - * @throws IdentityRecoveryServerException Error while getting the user store manager or triggering the event. - */ - private void triggerChallengeAnswersValidation(User user, UserChallengeAnswer[] userChallengeAnswers, - Map existingQuestionAndAnswers, String eventName) - throws IdentityRecoveryClientException, IdentityRecoveryServerException { - - Map properties = new HashMap<>(); - properties.put(IdentityEventConstants.EventProperty.USER, user); - properties.put(IdentityEventConstants.EventProperty.USER_CHALLENGE_ANSWERS, userChallengeAnswers); - properties.put(IdentityEventConstants.EventProperty.USER_OLD_CHALLENGE_ANSWERS, existingQuestionAndAnswers); - - try { - UserStoreManager userStoreManager; - if (IdentityUtil.getPrimaryDomainName().equals(user.getUserStoreDomain())) { - userStoreManager = (UserStoreManager) CarbonContext.getThreadLocalCarbonContext().getUserRealm() - .getUserStoreManager(); - } else { - userStoreManager = ((UserStoreManager) CarbonContext.getThreadLocalCarbonContext().getUserRealm() - .getUserStoreManager()).getSecondaryUserStoreManager(user.getUserStoreDomain()); - } - properties.put(IdentityEventConstants.EventProperty.USER_STORE_MANAGER, userStoreManager); - } catch (UserStoreException e) { - throw Utils.handleServerException(IdentityRecoveryConstants.ErrorMessages. - ERROR_CODE_FAILED_TO_LOAD_USER_STORE_MANAGER, null, e); - } - - Event identityMgtEvent = new Event(eventName, properties); - try { - IdentityRecoveryServiceDataHolder.getInstance().getIdentityEventService().handleEvent(identityMgtEvent); - } catch (IdentityEventClientException e) { - throw new IdentityRecoveryClientException(e.getErrorCode(), e.getMessage(), e); - } catch (IdentityEventServerException e) { - throw new IdentityRecoveryServerException(e.getErrorCode(), e.getMessage(), e); - } catch (IdentityEventException e) { - throw Utils.handleServerException(IdentityRecoveryConstants.ErrorMessages. - ERROR_CODE_PUBLISH_EVENT, eventName, e); - } - } - - private String getChallengeSeparator() { - String separator = IdentityUtil.getProperty(IdentityRecoveryConstants.ConnectorConfig - .QUESTION_CHALLENGE_SEPARATOR); - - if (StringUtils.isEmpty(separator)) { - separator = IdentityRecoveryConstants.DEFAULT_CHALLENGE_QUESTION_SEPARATOR; - } - return separator; - } - - /** - * @param user - * @param userChallengeAnswer - * @throws IdentityException - */ - public void setChallengeOfUser(User user, UserChallengeAnswer userChallengeAnswer) throws IdentityRecoveryException { - - validateUser(user); - - if (log.isDebugEnabled()) { - log.debug(String.format("Setting user challenge question answers in %s's profile.", user.toString())); - } - - try { - String tenantDomain = StringUtils.isBlank(user.getTenantDomain()) ? - MultitenantConstants.SUPER_TENANT_DOMAIN_NAME : user.getTenantDomain(); - - // validate whether two questions from the same set has been answered. - validateSecurityQuestionDuplicate(new UserChallengeAnswer[]{userChallengeAnswer}); - - // check whether the answered questions exist in the tenant domain - checkChallengeQuestionExists(new UserChallengeAnswer[]{userChallengeAnswer}, tenantDomain); - - Set challengesUris = new HashSet<>(getChallengeQuestionUris(user)); - String separator = getChallengeSeparator(); - - if (userChallengeAnswer.getQuestion().getQuestionSetId() != null && userChallengeAnswer.getQuestion().getQuestion() != - null && userChallengeAnswer.getAnswer() != null) { - String claimValue = userChallengeAnswer.getQuestion().getQuestion().trim() + separator + - Utils.doHash(userChallengeAnswer.getAnswer().trim().toLowerCase()); - Utils.setClaimInUserStoreManager(user, userChallengeAnswer.getQuestion().getQuestionSetId().trim(), - claimValue); - challengesUris.add(userChallengeAnswer.getQuestion().getQuestionSetId().trim()); - - setUserChallengesURI(user, challengesUris, separator); - } - } catch (org.wso2.carbon.user.api.UserStoreException e) { - throw Utils.handleServerException( - ERROR_CODE_REMOVING_CHALLENGE_QUESTIONS, user.getUserName(), e); - } - } - - private void setUserChallengesURI(User user, Set challengesUris, String separator) throws UserStoreException { - String challengesUrisValue = getUserChallengesUriValue(challengesUris, separator); - Utils.setClaimInUserStoreManager(user, IdentityRecoveryConstants.CHALLENGE_QUESTION_URI, challengesUrisValue); - } - - private void setUserChallengesURI(User user, Set challengesUris) throws UserStoreException { - setUserChallengesURI(user, challengesUris, getChallengeSeparator()); - } - - private String getUserChallengesUriValue(Set challengesUris, String separator) { - String challengesUrisValue = StringUtils.EMPTY; - for (String challengesUri : challengesUris) { - if (StringUtils.EMPTY.equals(challengesUrisValue)) { - challengesUrisValue = challengesUri; - } else { - challengesUrisValue = challengesUrisValue + - separator + challengesUri; - } - } - return challengesUrisValue; - } - - /** - * @param user - * @throws IdentityException - */ - public void removeChallengeAnswersOfUser(User user) throws - IdentityRecoveryException { - - validateUser(user); - if (log.isDebugEnabled()) { - log.debug("Removing Challenge question answers from the user profile."); - } - - List challengesUris = getChallengeQuestionUris(user); - challengesUris.add(IdentityRecoveryConstants.CHALLENGE_QUESTION_URI); - try { - Utils.removeClaimFromUserStoreManager(user, challengesUris.toArray(new String[challengesUris.size()])); - } catch (UserStoreException e) { - throw Utils.handleServerException( - ERROR_CODE_REMOVING_CHALLENGE_QUESTIONS, user.getUserName(), e); - } - } - - /** - * @param user - * @throws IdentityException - */ - public void removeChallengeAnswerOfUser(User user, String questionURI) throws - IdentityRecoveryException { - - validateUser(user); - if (log.isDebugEnabled()) { - log.debug("Removing a Challenge answer from the user profile."); - } - - Set challengesUris = new HashSet<>(getChallengeQuestionUris(user)); - if (challengesUris.contains(questionURI)) { - try { - Utils.removeClaimFromUserStoreManager(user, new String[]{questionURI}); - challengesUris.remove(questionURI); - setUserChallengesURI(user, challengesUris); - } catch (UserStoreException e) { - throw Utils.handleServerException(IdentityRecoveryConstants.ErrorMessages - .ERROR_CODE_GETTING_CHALLENGE_QUESTIONS, user.getUserName(), e); - } - } - } - - /** - * @param user - * @param userChallengeAnswers - * @return - */ - public boolean verifyChallengeAnswer(User user, UserChallengeAnswer[] userChallengeAnswers) throws - IdentityRecoveryException { - - validateUser(user); - - boolean verification = false; - if (log.isDebugEnabled()) { - log.debug(String.format("Verifying challenge question answers for %s.", user.toString())); - } - - UserChallengeAnswer[] storedAnswers = getChallengeAnswersOfUser(user); - - for (UserChallengeAnswer userChallengeAnswer : userChallengeAnswers) { - if (StringUtils.isBlank(userChallengeAnswer.getAnswer())) { - return false; - } - - for (UserChallengeAnswer storedAnswer : storedAnswers) { - if ((userChallengeAnswer.getQuestion().getQuestionSetId() == null || !userChallengeAnswer.getQuestion().getQuestionSetId() - .trim().equals(storedAnswer.getQuestion().getQuestionSetId())) && - (userChallengeAnswer.getQuestion().getQuestion() == null || !userChallengeAnswer.getQuestion().getQuestion(). - trim().equals(storedAnswer.getQuestion().getQuestion()))) { - continue; - - } - - String hashedAnswer = null; - try { - hashedAnswer = Utils.doHash(userChallengeAnswer.getAnswer().trim().toLowerCase()); - } catch (UserStoreException e) { - throw Utils.handleServerException(IdentityRecoveryConstants.ErrorMessages - .ERROR_CODE_NO_HASHING_ALGO, null, e); - } - - if (hashedAnswer.equals(storedAnswer.getAnswer())) { - verification = true; - } else { - return false; - } - } - } - - return verification; - } - - public boolean verifyUserChallengeAnswer(User user, UserChallengeAnswer userChallengeAnswer) - throws IdentityRecoveryException { - - // check whether user data are valid. - validateUser(user); - - boolean verification = false; - if (log.isDebugEnabled()) { - log.debug(String.format("Verifying challenge question answer for %s.", user.toString())); - } - - UserChallengeAnswer[] storedDto = getChallengeAnswersOfUser(user); - if (StringUtils.isBlank(userChallengeAnswer.getAnswer())) { - log.error("Invalid. Empty answer provided for the challenge question."); - return false; - } - - for (UserChallengeAnswer dto : storedDto) { - if (dto.getQuestion().getQuestionSetId().equals(userChallengeAnswer.getQuestion().getQuestionSetId())) { - String hashedAnswer = null; - try { - hashedAnswer = Utils.doHash(userChallengeAnswer.getAnswer().trim().toLowerCase()); - } catch (UserStoreException e) { - throw Utils.handleServerException(IdentityRecoveryConstants.ErrorMessages - .ERROR_CODE_NO_HASHING_ALGO, null, e); - } - if (hashedAnswer.equals(dto.getAnswer())) { - verification = true; - if (log.isDebugEnabled()) { - log.debug("Challenge question answer verified successfully."); - } - } else { - if (log.isDebugEnabled()) { - log.debug("Challenge question answer verification failed."); - } - return false; - } - } - } - - return verification; - } - - /** - * Check whether a challenge question exists in the tenant domain. Here we check whether a question exists with the - * given questionSetID, questionID and locale, if provided. - * - * @param challengeQuestion - * @param tenantDomain - * @return - * @throws IdentityRecoveryClientException - */ - private boolean isChallengeQuestionExists(ChallengeQuestion challengeQuestion, String tenantDomain) - throws IdentityRecoveryClientException { - validateChallengeQuestionMandatoryParams(challengeQuestion); - String questionPath = getQuestionPath(challengeQuestion); - - if (StringUtils.isNotEmpty(challengeQuestion.getLocale())) { - String locale = validateLocale(challengeQuestion.getLocale()); - return (resourceMgtService.getIdentityResource(questionPath, tenantDomain, locale) != null); - } - return (resourceMgtService.getIdentityResource(questionPath, tenantDomain) != null); - } - - /** - * Check whether a challenge question set exists in the tenant domain. - * Here we check whether a question set exists with questionSetID. - * - * @param questionSetID - * @param tenantDomain - * @return - * @throws IdentityRecoveryClientException - */ - private boolean isChallengeQuestionSetExists(String questionSetID, String tenantDomain) - throws IdentityRecoveryClientException { - validateChallengeSetURI(questionSetID); - String questionPath = getQuestionSetPath(questionSetID); - - return (resourceMgtService.getIdentityResource(questionPath, tenantDomain) != null); - } - - /** - * Create a challenge question object from the registry resource - * - * @param resource - * @return - */ - private ChallengeQuestion createChallengeQuestion(Resource resource) throws RegistryException { - ChallengeQuestion challengeQuestion = null; - - byte[] resourceContent = (byte[]) resource.getContent(); - - String questionText = new String(resourceContent, Charset.forName("UTF-8")); - String questionSetId = resource.getProperty(IdentityRecoveryConstants.Questions.CHALLENGE_QUESTION_SET_ID); - String questionId = resource.getProperty(IdentityRecoveryConstants.Questions.CHALLENGE_QUESTION_ID); - String questionLocale = resource.getProperty(IdentityRecoveryConstants.Questions.CHALLENGE_QUESTION_LOCALE); - - if (questionSetId != null) { - if (IdentityUtil.isBlank(questionLocale)) { - questionLocale = LOCALE_EN_US; - } - challengeQuestion = new ChallengeQuestion(questionSetId, questionId, questionText, questionLocale); - } - - return challengeQuestion; - } - - /** - * Create registry resource from a challenge question model object. - * - * @param question - * @return - * @throws RegistryException - */ - private Resource createRegistryResource(ChallengeQuestion question) throws RegistryException, UnsupportedEncodingException { - byte[] questionText = question.getQuestion().getBytes("UTF-8"); - String questionSetId = question.getQuestionSetId(); - String questionId = question.getQuestionId(); - String locale = question.getLocale(); - - Resource resource = new ResourceImpl(); - resource.setContent(questionText); - resource.addProperty(IdentityRecoveryConstants.Questions.CHALLENGE_QUESTION_SET_ID, questionSetId); - resource.addProperty(IdentityRecoveryConstants.Questions.CHALLENGE_QUESTION_ID, questionId); - resource.addProperty(IdentityRecoveryConstants.Questions.CHALLENGE_QUESTION_LOCALE, locale); // added locale - resource.setMediaType(RegistryConstants.TAG_MEDIA_TYPE); - - return resource; - } - - /** - * Get the relative path to the parent directory of the challenge question resource. - * - * @param challengeQuestion - * @return Path to the parent of challenge question relative to the root of the registry. - */ - private String getQuestionPath(ChallengeQuestion challengeQuestion) { - // challenge set uri - String questionSetIdUri = challengeQuestion.getQuestionSetId(); - String questionId = challengeQuestion.getQuestionId(); - - return getQuestionSetPath(questionSetIdUri) + RegistryConstants.PATH_SEPARATOR + questionId; - } - - /** - * Get the relative path to the parent directory of the challenge question resource. - * - * @param questionSetIdUri - * @return Path to the parent of challenge question relative to the root of the registry. - */ - private String getQuestionSetPath(String questionSetIdUri) { - - String questionSetId = Utils.getChallengeSetDirFromUri(questionSetIdUri); - - return QUESTIONS_BASE_PATH + RegistryConstants.PATH_SEPARATOR + questionSetId; - } - - - /** - * Validate whether two questions from the same question set have been answered (ie. we only allow a maximum of - * one question from each set) - * - * @param userChallengeAnswers - * @throws IdentityRecoveryException - */ - private void validateSecurityQuestionDuplicate(UserChallengeAnswer[] userChallengeAnswers) - throws IdentityRecoveryException { - - Set tmpMap = new HashSet<>(); - UserChallengeAnswer challengeAnswer; - ChallengeQuestion challengeQuestion; - - for (UserChallengeAnswer userChallengeAnswer : userChallengeAnswers) { - challengeAnswer = userChallengeAnswer; - challengeQuestion = challengeAnswer.getQuestion(); - // if there's no challenge question details we throw a client exception - if (challengeQuestion == null) { - String errorMsg = "Challenge question details not provided with the challenge answers."; - throw Utils.handleClientException( - IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_CHALLENGE_QUESTION_NOT_FOUND, errorMsg); - } - - if (tmpMap.contains(challengeQuestion.getQuestionSetId())) { - log.error(IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_DUPLICATE_ANSWERS.getMessage()); - throw Utils.handleClientException( - IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_DUPLICATE_ANSWERS, null); - } - tmpMap.add(challengeQuestion.getQuestionSetId()); - } - } - - - /** - * Check whether an answered challenge question actually exists in the tenant registry - * - * @param userChallengeAnswers - * @param tenantDomain - * @throws IdentityRecoveryClientException - */ - private void checkChallengeQuestionExists(UserChallengeAnswer[] userChallengeAnswers, String tenantDomain) - throws IdentityRecoveryException { - - for (UserChallengeAnswer challengeAnswer : userChallengeAnswers) { - ChallengeQuestion challengeQuestion = challengeAnswer.getQuestion(); - // if challenge question details are missing in the challenge answer we can't proceed further - if (challengeQuestion == null) { - throw Utils.handleClientException(ERROR_CODE_CHALLENG_ANSWER_MISSING, null); - } - - if (StringUtils.isBlank(challengeQuestion.getQuestion())) { - throw Utils.handleClientException(ERROR_CODE_INVALID_CHALLENGE_QUESTION_VALUE, null); - } - - String locale = validateLocale(challengeQuestion.getLocale()); - - List challengeQuestions = getAllChallengeQuestions(tenantDomain, locale); - boolean isQuestionAvailable = false; - for (ChallengeQuestion availableQuestion : challengeQuestions) { - if (StringUtils.equals(availableQuestion.getQuestionSetId(), challengeQuestion.getQuestionSetId().trim()) - && StringUtils.equals(availableQuestion.getQuestion().trim(), - challengeQuestion.getQuestion().trim() - )) { - isQuestionAvailable = true; - } - } - - if (!isQuestionAvailable) { - String error = "Error persisting user challenge answers for user. " + - "Challenge question answered is not registered with %s domain."; - throw Utils.handleClientException( - IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_CHALLENGE_QUESTION_NOT_FOUND, - String.format(error, tenantDomain)); - } - } - } - - - private String validateTenantDomain(String tenantDomain) { - return StringUtils.isBlank(tenantDomain) ? MultitenantConstants.SUPER_TENANT_DOMAIN_NAME : tenantDomain; - } - - - private String validateLocale(String locale) throws IdentityRecoveryClientException { - // if the locale is blank, we go with the default locale - if (StringUtils.isBlank(locale)) { - locale = LOCALE_EN_US; - } - // validate locale input string - if (locale.matches(IdentityRecoveryConstants.Questions.BLACKLIST_REGEX)) { - log.error("Invalid locale value provided : " + locale); - throw Utils.handleClientException(IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_INVALID_LOCALE, - locale); - } - - return locale; - - } - - private void validateUser(User user) throws IdentityRecoveryClientException { - if (user == null || StringUtils.isBlank(user.getUserName())) { - throw Utils.handleClientException( - IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_INVALID_USER, "Invalid User Data provided."); - } - } - - private void validateChallengeQuestionAttributes(ChallengeQuestion question) throws IdentityRecoveryClientException { - - String setId = question.getQuestionSetId(); - String questionId = question.getQuestionId(); - String questionText = question.getQuestion(); - String questionLocale = question.getLocale(); - - if (StringUtils.isBlank(setId) || StringUtils.isBlank(questionId) || StringUtils.isBlank(questionText) || - StringUtils.isBlank(questionLocale)) { - throw Utils.handleClientException(IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_INVALID_CHALLENGE, - null); - } - - - validateChallengePathParams(setId, questionId); - } - - private void validateChallengeQuestionMandatoryParams(ChallengeQuestion question) throws - IdentityRecoveryClientException { - - String setId = question.getQuestionSetId(); - String questionId = question.getQuestionId(); - - if (StringUtils.isBlank(setId) || StringUtils.isBlank(questionId)) { - throw Utils.handleClientException(IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_INVALID_CHALLENGE, - null); - } - validateChallengePathParams(setId, questionId); - } - - private void validateChallengePathParams(String setId, String questionId) throws IdentityRecoveryClientException { - validateChallengeSetURI(setId); - validateChallengePathParam(questionId, "QuestionId"); - } - - private void validateChallengeSetURI(String setId) throws IdentityRecoveryClientException { - String challengeSetDir = Utils.getChallengeSetDirFromUri(setId); - validateChallengePathParam(challengeSetDir, "ChallengeSetId"); - } - - private void validateChallengePathParam(String pathParam, String pathParamName) throws - IdentityRecoveryClientException { - if (StringUtils.isBlank(pathParam) || !StringUtils.isAlphanumeric(pathParam)) { - throw Utils.handleClientException(IdentityRecoveryConstants.ErrorMessages - .ERROR_CODE_INVALID_CHALLENGE_PATH, pathParamName); - } - } - - private String getLocaleOfUser(User user, String tenantDomain) throws IdentityRecoveryException { - String tenantAwareUserName = MultitenantUtils.getTenantAwareUsername(user.getUserName()); - String locale = IdentityRecoveryConstants.LOCALE_EN_US; - try { - String userLocale = - Utils.getClaimFromUserStoreManager(user, IdentityRecoveryConstants.Questions.LOCALE_CLAIM); - if (StringUtils.isNotBlank(userLocale)) { - locale = userLocale; - } - } catch (UserStoreException e) { - String errorMsg = String.format(IdentityRecoveryConstants.ErrorMessages - .ERROR_CODE_ERROR_RETRIVING_CLAIM.getMessage(), - tenantAwareUserName, tenantDomain); - log.error(errorMsg); - throw IdentityException.error(IdentityRecoveryServerException.class, IdentityRecoveryConstants.ErrorMessages - .ERROR_CODE_ERROR_RETRIVING_CLAIM.getCode(), errorMsg, e); - } - return locale; - } - -} diff --git a/components/org.wso2.carbon.identity.recovery/src/main/java/org/wso2/carbon/identity/recovery/bean/ChallengeQuestionResponse.java b/components/org.wso2.carbon.identity.recovery/src/main/java/org/wso2/carbon/identity/recovery/bean/ChallengeQuestionResponse.java deleted file mode 100644 index d2aa140c2e..0000000000 --- a/components/org.wso2.carbon.identity.recovery/src/main/java/org/wso2/carbon/identity/recovery/bean/ChallengeQuestionResponse.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * - * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. - * - * WSO2 Inc. 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.recovery.bean; - -import org.wso2.carbon.identity.recovery.model.ChallengeQuestion; - -public class ChallengeQuestionResponse { - - private ChallengeQuestion question; - private String code; - private String status; - - public ChallengeQuestionResponse() { - //Default constructor - } - - public ChallengeQuestionResponse(ChallengeQuestion question) { - this.question = question; - } - - public ChallengeQuestion getQuestion() { - return question; - } - - public void setQuestion(ChallengeQuestion question) { - this.question = question; - } - - public String getCode() { - return code; - } - - public void setCode(String code) { - this.code = code; - } - - public String getStatus() { - return status; - } - - public void setStatus(String status) { - this.status = status; - } -} \ No newline at end of file diff --git a/components/org.wso2.carbon.identity.recovery/src/main/java/org/wso2/carbon/identity/recovery/bean/ChallengeQuestionsResponse.java b/components/org.wso2.carbon.identity.recovery/src/main/java/org/wso2/carbon/identity/recovery/bean/ChallengeQuestionsResponse.java deleted file mode 100644 index 593e76d556..0000000000 --- a/components/org.wso2.carbon.identity.recovery/src/main/java/org/wso2/carbon/identity/recovery/bean/ChallengeQuestionsResponse.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * - * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. - * - * WSO2 Inc. 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.recovery.bean; - -import org.wso2.carbon.identity.recovery.model.ChallengeQuestion; - -public class ChallengeQuestionsResponse { - - private ChallengeQuestion[] question; - private String code; - private String status; - - public ChallengeQuestionsResponse() { - //Default constructor - } - - public ChallengeQuestionsResponse(ChallengeQuestion[] question) { - if (question != null) { - this.question = question.clone(); - } - } - - public ChallengeQuestion[] getQuestion() { - if (question == null) { - return new ChallengeQuestion[0]; - } - return question; - } - - public void setQuestion(ChallengeQuestion[] question) { - if (question != null) { - this.question = question.clone(); - } - } - - public String getCode() { - return code; - } - - public void setCode(String code) { - this.code = code; - } - - public String getStatus() { - return status; - } - - public void setStatus(String status) { - this.status = status; - } -} \ No newline at end of file diff --git a/components/org.wso2.carbon.identity.recovery/src/main/java/org/wso2/carbon/identity/recovery/handler/ChallengeAnswerValidationHandler.java b/components/org.wso2.carbon.identity.recovery/src/main/java/org/wso2/carbon/identity/recovery/handler/ChallengeAnswerValidationHandler.java deleted file mode 100644 index 84e1d347ef..0000000000 --- a/components/org.wso2.carbon.identity.recovery/src/main/java/org/wso2/carbon/identity/recovery/handler/ChallengeAnswerValidationHandler.java +++ /dev/null @@ -1,222 +0,0 @@ -/* - * Copyright (c) 2020, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. - * - * WSO2 Inc. 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.recovery.handler; - -import org.apache.commons.lang.StringUtils; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.wso2.carbon.identity.application.common.model.User; -import org.wso2.carbon.identity.core.bean.context.MessageContext; -import org.wso2.carbon.identity.core.util.IdentityUtil; -import org.wso2.carbon.identity.event.IdentityEventClientException; -import org.wso2.carbon.identity.event.IdentityEventConstants; -import org.wso2.carbon.identity.event.IdentityEventException; -import org.wso2.carbon.identity.event.IdentityEventServerException; -import org.wso2.carbon.identity.event.event.Event; -import org.wso2.carbon.identity.event.handler.AbstractEventHandler; -import org.wso2.carbon.identity.recovery.IdentityRecoveryClientException; -import org.wso2.carbon.identity.recovery.IdentityRecoveryConstants; -import org.wso2.carbon.identity.recovery.IdentityRecoveryServerException; -import org.wso2.carbon.identity.recovery.model.ChallengeQuestion; -import org.wso2.carbon.identity.recovery.model.UserChallengeAnswer; -import org.wso2.carbon.identity.recovery.util.Utils; -import org.wso2.carbon.user.api.UserStoreException; -import org.wso2.carbon.user.core.UserCoreConstants; -import org.wso2.carbon.user.core.UserStoreManager; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; - -/** - * This class is used to validate the challenge question answers. - */ -public class ChallengeAnswerValidationHandler extends AbstractEventHandler { - - private static final Log log = LogFactory.getLog(ChallengeAnswerValidationHandler.class); - - public String getName() { - - return "challengeAnswerValidation"; - } - - @Override - public int getPriority(MessageContext messageContext) { - - return 50; - } - - @Override - public void handleEvent(Event event) throws IdentityEventException { - - String eventName = event.getEventName(); - Map eventProperties = event.getEventProperties(); - UserStoreManager userStoreManager = (UserStoreManager) eventProperties. - get(IdentityEventConstants.EventProperty.USER_STORE_MANAGER); - User user = (User) eventProperties.get(IdentityEventConstants.EventProperty.USER); - UserChallengeAnswer[] userChallengeAnswers = (UserChallengeAnswer[]) eventProperties. - get(IdentityEventConstants.EventProperty.USER_CHALLENGE_ANSWERS); - Map existingQuestionAndAnswers = (Map) - eventProperties.get(IdentityEventConstants.EventProperty.USER_OLD_CHALLENGE_ANSWERS); - user.setUserStoreDomain(userStoreManager.getRealmConfiguration(). - getUserStoreProperty(UserCoreConstants.RealmConfig.PROPERTY_DOMAIN_NAME)); - - if (IdentityEventConstants.Event.PRE_SET_CHALLENGE_QUESTION_ANSWERS.equals(eventName)) { - try { - validateChallengeAnswers(user, userChallengeAnswers, existingQuestionAndAnswers); - } catch (IdentityRecoveryClientException e) { - throw new IdentityEventClientException(e.getErrorCode(), e.getMessage(), e); - } catch (IdentityRecoveryServerException e) { - throw new IdentityEventServerException(e.getErrorCode(), e.getMessage(), e); - } - } - } - - /** - * Validate challenge answers. - * - * @param user User. - * @param userChallengeAnswers Challenge Answers. - * @param existingQuestionAndAnswers Previously stored answers. - * @throws IdentityEventException If an error occurred while reading the configurations. - * @throws IdentityRecoveryClientException If an invalid answers was given. - * @throws IdentityRecoveryServerException If an error occurred while hashing the answers. - */ - private void validateChallengeAnswers(User user, UserChallengeAnswer[] userChallengeAnswers, - Map existingQuestionAndAnswers) - throws IdentityEventException, IdentityRecoveryClientException, IdentityRecoveryServerException { - - Map> challengeAnswers = filterChallengeAnswers(userChallengeAnswers, - existingQuestionAndAnswers); - List existingChallengeAnswers = challengeAnswers. - get(IdentityRecoveryConstants.USER_OLD_CHALLENGE_ANSWERS); - List newChallengeAnswers = challengeAnswers. - get(IdentityRecoveryConstants.USER_NEW_CHALLENGE_ANSWERS); - validateChallengeAnswerRegex(user.getTenantDomain(), newChallengeAnswers); - if (Boolean.parseBoolean(Utils.getConnectorConfig(IdentityRecoveryConstants.ConnectorConfig. - ENFORCE_CHALLENGE_QUESTION_ANSWER_UNIQUENESS, user.getTenantDomain()))) { - validateChallengeAnswerUniqueness(newChallengeAnswers, existingChallengeAnswers); - } - } - - /** - * Filter previously stored and newly added answers of the challenge questions. - * - * @param userChallengeAnswers List of UserChallengeAnswer objects. - * @param existingQuestionAndAnswers Map of existing challenge question and answers. - * @return Map of existing and new challenge answers. - */ - private Map> filterChallengeAnswers(UserChallengeAnswer[] userChallengeAnswers, - Map existingQuestionAndAnswers) { - - Map> challengeAnswers = new HashMap<>(); - List existingChallengeAnswers = new ArrayList<>(); - List newChallengeAnswers = new ArrayList<>(); - String separator = IdentityUtil.getProperty(IdentityRecoveryConstants.ConnectorConfig - .QUESTION_CHALLENGE_SEPARATOR); - for (UserChallengeAnswer userChallengeAnswer : userChallengeAnswers) { - ChallengeQuestion challengeQuestion = userChallengeAnswer.getQuestion(); - if (StringUtils.isNotBlank(challengeQuestion.getQuestionSetId()) && - StringUtils.isNotBlank(challengeQuestion.getQuestion()) - && StringUtils.isNotBlank(userChallengeAnswer.getAnswer())) { - String oldValue = existingQuestionAndAnswers - .get(challengeQuestion.getQuestionSetId().trim()); - if (StringUtils.isNotBlank(oldValue) && oldValue.contains(separator)) { - String oldAnswer = oldValue.split(separator)[1]; - if (oldAnswer.trim().equals(userChallengeAnswer.getAnswer().trim())) { - existingChallengeAnswers.add(userChallengeAnswer); - } else { - newChallengeAnswers.add(userChallengeAnswer); - } - } else { - newChallengeAnswers.add(userChallengeAnswer); - } - } - } - challengeAnswers.put(IdentityRecoveryConstants.USER_OLD_CHALLENGE_ANSWERS, existingChallengeAnswers); - challengeAnswers.put(IdentityRecoveryConstants.USER_NEW_CHALLENGE_ANSWERS, newChallengeAnswers); - return challengeAnswers; - } - - /** - * Validate the challenge question answer regex. - * - * @param tenantDomain Tenant Domain. - * @param newChallengeAnswers Newly added challenge question answers. - * @throws IdentityEventException Error while reading the configurations. - * @throws IdentityRecoveryClientException Error while validating the answer regex. - */ - private void validateChallengeAnswerRegex(String tenantDomain, - List newChallengeAnswers) - throws IdentityRecoveryClientException, IdentityEventException { - - for (UserChallengeAnswer userChallengeAnswer : newChallengeAnswers) { - String challengeQuestion = userChallengeAnswer.getQuestion().getQuestion(); - if (!(userChallengeAnswer.getAnswer()).matches(Utils.getConnectorConfig(IdentityRecoveryConstants. - ConnectorConfig.CHALLENGE_QUESTION_ANSWER_REGEX, tenantDomain))) { - if (log.isDebugEnabled()) { - log.debug(String.format("The challenge question answer for the question, '%s' is not in the " + - "expected format.", challengeQuestion)); - } - throw Utils.handleClientException( - IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_INVALID_ANSWER_FORMAT, challengeQuestion); - } - } - } - - /** - * Validate the uniqueness of a given answer. - * - * @param newChallengeAnswers Newly added challenge question answers. - * @param existingChallengeAnswers Existing challenge question answers. - * @throws IdentityRecoveryServerException Error while hashing the newly added answers. - * @throws IdentityRecoveryClientException Error while validating the answer uniqueness. - */ - private void validateChallengeAnswerUniqueness(List newChallengeAnswers, - List existingChallengeAnswers) - throws IdentityRecoveryServerException, IdentityRecoveryClientException { - - Set uniqueChallengeAnswerHashSet = new HashSet<>(); - for (UserChallengeAnswer existingChallengeAnswer : existingChallengeAnswers) { - uniqueChallengeAnswerHashSet.add(existingChallengeAnswer.getAnswer().trim()); - } - - String hashedNewChallengeAnswer; - for (UserChallengeAnswer userChallengeAnswer : newChallengeAnswers) { - String challengeQuestion = userChallengeAnswer.getQuestion().getQuestion(); - try { - hashedNewChallengeAnswer = Utils.doHash(userChallengeAnswer.getAnswer().trim().toLowerCase()); - } catch (UserStoreException e) { - throw Utils.handleServerException( - IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_NO_HASHING_ALGO, null); - } - if (!uniqueChallengeAnswerHashSet.add(hashedNewChallengeAnswer)) { - if (log.isDebugEnabled()) { - log.debug(String.format("The challenge question answer is not unique. The given answer for " + - "the challenge question '%s' has been used more than once.", challengeQuestion)); - } - throw Utils.handleClientException(IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_NOT_UNIQUE_ANSWER, - challengeQuestion); - } - } - } -} diff --git a/components/org.wso2.carbon.identity.recovery/src/main/java/org/wso2/carbon/identity/recovery/handler/request/PostAuthnMissingChallengeQuestionsHandler.java b/components/org.wso2.carbon.identity.recovery/src/main/java/org/wso2/carbon/identity/recovery/handler/request/PostAuthnMissingChallengeQuestionsHandler.java deleted file mode 100644 index bfd158b0bd..0000000000 --- a/components/org.wso2.carbon.identity.recovery/src/main/java/org/wso2/carbon/identity/recovery/handler/request/PostAuthnMissingChallengeQuestionsHandler.java +++ /dev/null @@ -1,504 +0,0 @@ -/* - * Copyright (c) 2018, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. - * - * WSO2 Inc. 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.recovery.handler.request; - -import org.apache.commons.collections.CollectionUtils; -import org.apache.commons.lang.StringUtils; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.wso2.carbon.identity.application.authentication.framework.config.ConfigurationFacade; -import org.wso2.carbon.identity.application.authentication.framework.context.AuthenticationContext; -import org.wso2.carbon.identity.application.authentication.framework.exception.PostAuthenticationFailedException; -import org.wso2.carbon.identity.application.authentication.framework.handler.request.AbstractPostAuthnHandler; -import org.wso2.carbon.identity.application.authentication.framework.handler.request.PostAuthnHandlerFlowStatus; -import org.wso2.carbon.identity.application.authentication.framework.model.AuthenticatedUser; -import org.wso2.carbon.identity.application.common.model.IdentityProvider; -import org.wso2.carbon.identity.application.common.model.IdentityProviderProperty; -import org.wso2.carbon.identity.application.common.model.User; -import org.wso2.carbon.identity.base.IdentityException; -import org.wso2.carbon.identity.mgt.util.Utils; -import org.wso2.carbon.identity.recovery.ChallengeQuestionManager; -import org.wso2.carbon.identity.recovery.IdentityRecoveryConstants; -import org.wso2.carbon.identity.recovery.IdentityRecoveryException; -import org.wso2.carbon.identity.recovery.IdentityRecoveryServerException; -import org.wso2.carbon.identity.recovery.internal.IdentityRecoveryServiceDataHolder; -import org.wso2.carbon.identity.recovery.model.ChallengeQuestion; -import org.wso2.carbon.identity.recovery.model.UserChallengeAnswer; -import org.wso2.carbon.idp.mgt.IdentityProviderManagementException; -import org.wso2.carbon.idp.mgt.IdentityProviderManager; -import org.wso2.carbon.user.api.UserStoreException; -import org.wso2.carbon.user.core.UserCoreConstants; -import org.wso2.carbon.user.core.UserStoreManager; -import org.wso2.carbon.user.core.service.RealmService; -import org.wso2.carbon.user.core.util.UserCoreUtil; - -import java.io.IOException; -import java.io.UnsupportedEncodingException; -import java.nio.charset.StandardCharsets; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.Enumeration; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -/** - * This class will check whether the challenge questions are set for the user. - * Also, It will force users to add answers to challenge questions if challenge questions are not - * already answered - **/ - -public class PostAuthnMissingChallengeQuestionsHandler extends AbstractPostAuthnHandler { - - private static final String CHALLENGE_QUESTIONS_REQUESTED = "challengeQuestionsRequested"; - private static final String SELECTED_CHALLENGE_QUESTION_PREFIX = "Q-"; - private static final String CHALLENGE_QUESTION_ANSWER_PREFIX = "A-"; - - private static final Log log = LogFactory.getLog(PostAuthnMissingChallengeQuestionsHandler.class); - private static volatile PostAuthnMissingChallengeQuestionsHandler instance = - new PostAuthnMissingChallengeQuestionsHandler(); - - public static PostAuthnMissingChallengeQuestionsHandler getInstance() { - - return instance; - } - - /** - * To avoid creation of multiple instances of this handler. - */ - private PostAuthnMissingChallengeQuestionsHandler() { - } - - @Override - public PostAuthnHandlerFlowStatus handle(HttpServletRequest httpServletRequest, - HttpServletResponse httpServletResponse, - AuthenticationContext authenticationContext) - throws PostAuthenticationFailedException { - - if (log.isDebugEnabled()) { - log.debug("Post authentication handling for missing security questions has started"); - } - - if (authenticationContext == null || authenticationContext.getSequenceConfig() == null - || authenticationContext.getSequenceConfig().getAuthenticatedUser() == null) { - if (log.isDebugEnabled()) { - log.debug("Authentication context or sequence config or authenticated user is null."); - } - return PostAuthnHandlerFlowStatus.UNSUCCESS_COMPLETED; - } - - String forceChallengeQuestionConfig = getResidentIdpProperty(authenticationContext.getTenantDomain(), - IdentityRecoveryConstants.ConnectorConfig.FORCE_ADD_PW_RECOVERY_QUESTION); - String minimumForcedChallengeQuestionsAnswered = getResidentIdpProperty(authenticationContext.getTenantDomain(), - IdentityRecoveryConstants.ConnectorConfig.FORCE_MIN_NO_QUESTION_ANSWERED); - - if (StringUtils.isBlank(forceChallengeQuestionConfig)) { - // Exit post authentication handler if the value for the resident IDP setting not found - if (log.isDebugEnabled()) { - log.debug("Resident IdP value not found for " + IdentityRecoveryConstants.ConnectorConfig - .FORCE_ADD_PW_RECOVERY_QUESTION + " hence exiting from " + - "PostAuthnMissingChallengeQuestionsHandler"); - } - return PostAuthnHandlerFlowStatus.UNSUCCESS_COMPLETED; - - } else if (Boolean.parseBoolean(forceChallengeQuestionConfig)) { - // Execute the post authentication handler logic if the relevant setting is enabled at resident IDP - AuthenticatedUser user = getAuthenticatedUser(authenticationContext); - // Return from PostAuthnMissingChallengeQuestionsHandler if no authenticated user found - if (user == null) { - if (log.isDebugEnabled()) { - log.debug("No authenticated user found. Hence returning without handling missing security" + - " questions"); - } - return PostAuthnHandlerFlowStatus.UNSUCCESS_COMPLETED; - } - // Return from the post authentication handler if the user is Federated user - if (user.isFederatedUser()) { - return PostAuthnHandlerFlowStatus.SUCCESS_COMPLETED; - } - // Check whether the user already added sufficient security questions. - if (isChallengeQuestionsProvided(user, minimumForcedChallengeQuestionsAnswered)) { - // Return from post authenticator with Success status - return PostAuthnHandlerFlowStatus.SUCCESS_COMPLETED; - } - boolean challengeQuestionsRequested = isChallengeQuestionRequested(authenticationContext); - if (challengeQuestionsRequested) { - return handleMissingChallengeQuestionResponse(httpServletRequest, user); - } else { - return handleMissingChallengeQuestionRequest(httpServletResponse, - authenticationContext, user); - } - } - return PostAuthnHandlerFlowStatus.SUCCESS_COMPLETED; - } - - /** - * Returns the authenticated user form the authentication context. - * - * @param authenticationContext Authentication Context. - * @return AuthenticatedUser Authenticated User. - */ - private AuthenticatedUser getAuthenticatedUser(AuthenticationContext authenticationContext) { - return authenticationContext.getSequenceConfig().getAuthenticatedUser(); - } - - /** - * Checks for the Challenge Question Requested Parameter in the authentication context - * - * @param authenticationContext Authentication Context. - * @return Boolean value for the Challenge Question requested parameter of authenticationContext. - */ - @SuppressWarnings("unchecked") - private boolean isChallengeQuestionRequested(AuthenticationContext authenticationContext) { - return (authenticationContext.getParameter(CHALLENGE_QUESTIONS_REQUESTED) == Boolean.TRUE); - } - - /** - * Set the Challenge Question Requested parameter in the authenticated context. - * - * @param authenticationContext Authentication Context. - */ - @SuppressWarnings("unchecked") - private void setChallengeQuestionRequestedState(AuthenticationContext authenticationContext) { - authenticationContext.addParameter(CHALLENGE_QUESTIONS_REQUESTED, true); - } - - @Override - public String getName() { - return "PostAuthnMissingChallengeQuestionsHandler"; - } - - /** - * Returns the property related to the key from the Resident IDP properties. - * - * @param tenantDomain Tenant Domain. - * @param key Name of the resident IDP property to find in the Resident IDP - * @return String value of the requested property. - */ - private String getResidentIdpProperty(String tenantDomain, String key) { - IdentityProvider residentIdp; - - try { - residentIdp = IdentityProviderManager.getInstance().getResidentIdP(tenantDomain); - IdentityProviderProperty[] idpProps = residentIdp.getIdpProperties(); - for (IdentityProviderProperty property : idpProps) { - if (StringUtils.equals(property.getName(), key)) { - return property.getValue(); - } - } - return StringUtils.EMPTY; - } catch (IdentityProviderManagementException e) { - log.error("Resident IdP value not found. Error while retrieving resident IdP property " + - "for force challenge question ", e); - return StringUtils.EMPTY; - } - } - - /** - * Returns whether the user has already provided the challenge questions. - * - * @param user User Authenticated User. - * @param minimumForcedChallengeQuestionsAnswered Minimum number of challenge questions forced should be answered. - * @return Boolean value indicating whether the user has already provided challenge questions. - */ - private boolean isChallengeQuestionsProvided(AuthenticatedUser user, - String minimumForcedChallengeQuestionsAnswered) { - - int questionsAnswered = getUserAnsweredChallengeSetUris(user).size(); - int challengeQuestionSets = getChallengeSetUris(user).size(); - /* If "Minimum Number of Forced Challenge Questions to be Answered" property is not configured, - check whether the user has answered for at least one question. As "Minimum Number of Forced Challenge - Questions to be Answered" property has a default value "1", the property not configured scenario - can be occurred only from mgt console. - */ - if (StringUtils.isEmpty(minimumForcedChallengeQuestionsAnswered)) { - return (questionsAnswered > 0); - } - /* If "Minimum Number of Forced Challenge Questions to be Answered" property is configured, - check whether the user has answered at least minimum number of forced questions or check whether the - user has already answered to all available question sets. - */ - return (Integer.parseInt(minimumForcedChallengeQuestionsAnswered) <= questionsAnswered) || - (questionsAnswered == challengeQuestionSets); - } - - /** - * Returns a list of challenge questions for a given user. - * - * @param user Authenticated User. - * @return List of ChallengeQuestions. - */ - private List getChallengeQuestions(AuthenticatedUser user) { - String tenantDomain = user.getTenantDomain(); - - try { - return ChallengeQuestionManager.getInstance().getAllChallengeQuestions(tenantDomain); - } catch (IdentityRecoveryServerException e) { - log.error("Identity recovery server error occurred for user:" + user.getUserName(), e); - return null; - } - } - - /** - * Return a list of challenge questions set URIs for a given user. - * - * @param user Authenticated User. - * @return List of Challenge question sets URI. - */ - private List getChallengeSetUris(AuthenticatedUser user) { - - List challengeQuestions = getChallengeQuestions(user); - HashSet questionSetNames = new HashSet<>(); - if (CollectionUtils.isEmpty(challengeQuestions)) { - return new ArrayList<>(); - } - for (ChallengeQuestion question : challengeQuestions) { - if (StringUtils.isNotBlank(question.getQuestionSetId())) { - questionSetNames.add(question.getQuestionSetId()); - } - } - List challengeSetUriList = new ArrayList<>(questionSetNames); - Collections.sort(challengeSetUriList); - return challengeSetUriList; - } - - /** - * Return a list of challenge question sets URIs that user answered. - * - * @param user Authenticated user. - * @return List of challenge question set URIs answered by user. - * @throws IdentityException Exception occurred while retrieving tenant ID for the user. - * @throws UserStoreException Exception occurred while retrieving tenant ID for the user. - */ - private List getUserAnsweredChallengeSetUris(AuthenticatedUser user) { - - List questionSetsAnswered = new ArrayList<>(); - String userName = UserCoreUtil.addDomainToName(user.getUserName(), user.getUserStoreDomain()); - try { - int tenantId = Utils.getTenantId(user.getTenantDomain()); - UserStoreManager userStoreManager = getUserStoreManager(tenantId); - if (userStoreManager != null) { - Map claimsMap = userStoreManager - .getUserClaimValues(userName, new String[]{IdentityRecoveryConstants.CHALLENGE_QUESTION_URI}, - UserCoreConstants.DEFAULT_PROFILE); - String claimValue = claimsMap.get(IdentityRecoveryConstants.CHALLENGE_QUESTION_URI); - if (StringUtils.isBlank(claimValue)) { - return questionSetsAnswered; - } - questionSetsAnswered = - Arrays.asList(claimValue.split(IdentityRecoveryConstants.DEFAULT_CHALLENGE_QUESTION_SEPARATOR)); - } - } catch (IdentityException | UserStoreException e) { - log.error("Exception occurred while retrieving tenant ID for the user :" + userName, e); - } - return questionSetsAnswered; - } - - /** - * Get UserStoreManager. - * - * @param tenantId Tenant id. - * @return UserStoreManager object. - * @throws IdentityRecoveryServerException Error getting UserStoreManager - */ - private UserStoreManager getUserStoreManager(int tenantId) throws IdentityRecoveryServerException { - - UserStoreManager userStoreManager; - RealmService realmService = IdentityRecoveryServiceDataHolder.getInstance().getRealmService(); - try { - if (realmService.getTenantUserRealm(tenantId) != null) { - userStoreManager = (UserStoreManager) realmService.getTenantUserRealm(tenantId). - getUserStoreManager(); - } else { - throw org.wso2.carbon.identity.recovery.util.Utils.handleServerException( - IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_ERROR_GETTING_USERSTORE_MANAGER, null); - } - } catch (UserStoreException e) { - if (log.isDebugEnabled()) { - String error = String.format("Error retrieving the user store manager for the tenant : %s", tenantId); - log.debug(error, e); - } - throw org.wso2.carbon.identity.recovery.util.Utils.handleServerException( - IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_ERROR_GETTING_USERSTORE_MANAGER, null, e); - } - return userStoreManager; - } - - /** - * Set the challenge questions for the user by calling ChallengeQuestionManger. - * - * @param user Authenticated User. - * @param userChallengeAnswers Array of UserChallengeAnswer - */ - private void setChallengeQuestionAnswers(User user, UserChallengeAnswer[] userChallengeAnswers) { - - try { - ChallengeQuestionManager.getInstance().setChallengesOfUser(user, userChallengeAnswers); - } catch (IdentityRecoveryException e) { - log.error("Unable to save challenge question answers for user : " + user.getUserName(), e); - } - } - - /** - * Returns an array of UserChallengeAnswer from constructed from the servlet request parameters - * - * @param servletRequest HTTP Servlet Request. - * @return challengeQuestionList. - */ - private UserChallengeAnswer[] retrieveChallengeQuestionAnswers(HttpServletRequest servletRequest, - List challengeQuestionsList) { - Map questionsMap = new HashMap<>(); - Map answersMap = new HashMap<>(); - List questionsAndAnswers = new ArrayList<>(); - - Enumeration paramNames = servletRequest.getParameterNames(); - List paramNamesList = Collections.list(paramNames); - - for (String requestParam : paramNamesList) { - if (requestParam.contains(SELECTED_CHALLENGE_QUESTION_PREFIX)) { - String question = servletRequest.getParameter(requestParam); - String questionSetID = requestParam.replace(SELECTED_CHALLENGE_QUESTION_PREFIX, ""); - questionsMap.put(questionSetID, question); - - } else if (requestParam.contains(CHALLENGE_QUESTION_ANSWER_PREFIX)) { - String answer = servletRequest.getParameter(requestParam); - String answerSetID = requestParam.replace(CHALLENGE_QUESTION_ANSWER_PREFIX, ""); - answersMap.put(answerSetID, answer); - } - } - for (String questionKey : questionsMap.keySet()) { - String challengeQuestion = questionsMap.get(questionKey); - for (ChallengeQuestion question : challengeQuestionsList) { - if (StringUtils.equals(question.getQuestionSetId(), questionKey) && - StringUtils.equals(question.getQuestion(), challengeQuestion)) { - UserChallengeAnswer questionAndAnswer = new UserChallengeAnswer(); - questionAndAnswer.setQuestion(question); - if (StringUtils.isEmpty(answersMap.get(questionKey))) { - if (log.isDebugEnabled()) { - log.debug("Answer not found for challenge question " + question + ", hence not adding " + - "challenge question"); - } - } else { - questionAndAnswer.setAnswer(answersMap.get(questionKey)); - questionsAndAnswers.add(questionAndAnswer); - } - } - } - } - return questionsAndAnswers.toArray(new UserChallengeAnswer[questionsAndAnswers.size()]); - } - - /** - * Returns a URL-encoded string of challenge questions for the given user - * - * @param user Authenticated User. - * @return UTF-8 encoded URL with challenge questions. - */ - private String getUrlEncodedChallengeQuestionsString(AuthenticatedUser user) throws UnsupportedEncodingException { - - StringBuilder challengeQuestionData = new StringBuilder(); - List challengeQuestionList = getChallengeQuestions(user); - - if (CollectionUtils.isEmpty(challengeQuestionList)) { - if (log.isDebugEnabled()) { - log.debug("Challenge questions not found for the user: " + user.getUserName() + " in tenant domain: " - + user.getTenantDomain()); - } - return null; - } else { - for (ChallengeQuestion question : challengeQuestionList) { - String setId = question.getQuestionSetId(); - String questionId = question.getQuestionId(); - String questionString = question.getQuestion(); - String questionLocale = question.getLocale(); - challengeQuestionData.append(setId).append("|").append(questionId).append("|").append - (questionString).append("|").append(questionLocale).append("&"); - } - } - return java.net.URLEncoder.encode(challengeQuestionData.toString(), StandardCharsets.UTF_8.name()); - } - - /** - * This handles the PostAuthentication Requests for PostAuthnMissingChallengeQuestionHandler - * - * @param httpServletResponse HTTP Servlet Response. - * @param authenticationContext Authentication Context - * @param user Authenticated User - * @return PostAuthnHandlerFlowStatus Flow status of the PostAuthentication Handler - */ - private PostAuthnHandlerFlowStatus handleMissingChallengeQuestionRequest( - HttpServletResponse httpServletResponse, AuthenticationContext authenticationContext, - AuthenticatedUser user) { - - // If challenge questions are not requested redirect user to add challenge questions jsp page - String encodedData = null; - try { - encodedData = getUrlEncodedChallengeQuestionsString(user); - } catch (UnsupportedEncodingException e) { - log.error("Error occurred while URL-encoding the challenge question data", e); - } - - if (StringUtils.isBlank(encodedData)) { - if (log.isDebugEnabled()) { - log.debug("Unable to get challenge questions for user : " + user.getUserName() + " for " + - "tenant domain : " + authenticationContext.getTenantDomain()); - } - return PostAuthnHandlerFlowStatus.UNSUCCESS_COMPLETED; - } - - try { - // Redirect the user to fill the answers for challenge questions - httpServletResponse.sendRedirect - (ConfigurationFacade.getInstance().getAuthenticationEndpointURL().replace("/login.do", "" - ) + "/add-security-questions" + ".jsp?sessionDataKey=" + - authenticationContext.getContextIdentifier() + "&data=" + encodedData + "&sp=" + - authenticationContext.getServiceProviderName()); - setChallengeQuestionRequestedState(authenticationContext); - return PostAuthnHandlerFlowStatus.INCOMPLETE; - - } catch (IOException e) { - log.error("Error occurred while redirecting to challenge questions page", e); - return PostAuthnHandlerFlowStatus.UNSUCCESS_COMPLETED; - } - } - - /** - * This handles the PostAuthentication Response for PostAuthnMissingChallengeQuestionHandler - * - * @param httpServletRequest HTTP Servlet Request. - * @param user Authenticated User - * @return PostAuthnHandlerFlowStatus Flow status of the PostAuthentication Handler - */ - private PostAuthnHandlerFlowStatus handleMissingChallengeQuestionResponse( - HttpServletRequest httpServletRequest, AuthenticatedUser user) { - - // If user already redirected to add challenge questions add answers for challenge questions - List challengeQuestionList = getChallengeQuestions(user); - UserChallengeAnswer[] answersForChallengeQuestions = retrieveChallengeQuestionAnswers - (httpServletRequest, challengeQuestionList); - setChallengeQuestionAnswers(user, answersForChallengeQuestions); - - return PostAuthnHandlerFlowStatus.SUCCESS_COMPLETED; - } - -} diff --git a/components/org.wso2.carbon.identity.recovery/src/main/java/org/wso2/carbon/identity/recovery/internal/IdentityRecoveryServiceComponent.java b/components/org.wso2.carbon.identity.recovery/src/main/java/org/wso2/carbon/identity/recovery/internal/IdentityRecoveryServiceComponent.java index b5114c2d90..73033aa177 100644 --- a/components/org.wso2.carbon.identity.recovery/src/main/java/org/wso2/carbon/identity/recovery/internal/IdentityRecoveryServiceComponent.java +++ b/components/org.wso2.carbon.identity.recovery/src/main/java/org/wso2/carbon/identity/recovery/internal/IdentityRecoveryServiceComponent.java @@ -45,7 +45,6 @@ import org.wso2.carbon.identity.input.validation.mgt.services.InputValidationManagementService; import org.wso2.carbon.identity.input.validation.mgt.services.InputValidationManagementServiceImpl; import org.wso2.carbon.identity.multi.attribute.login.mgt.MultiAttributeLoginService; -import org.wso2.carbon.identity.recovery.ChallengeQuestionManager; import org.wso2.carbon.identity.recovery.IdentityRecoveryException; import org.wso2.carbon.identity.recovery.confirmation.ResendConfirmationManager; import org.wso2.carbon.identity.recovery.connector.AdminForcedPasswordResetConfigImpl; @@ -56,7 +55,6 @@ import org.wso2.carbon.identity.recovery.connector.UserEmailVerificationConfigImpl; import org.wso2.carbon.identity.recovery.handler.AccountConfirmationValidationHandler; import org.wso2.carbon.identity.recovery.handler.AdminForcedPasswordResetHandler; -import org.wso2.carbon.identity.recovery.handler.ChallengeAnswerValidationHandler; import org.wso2.carbon.identity.recovery.handler.CodeInvalidationHandler; import org.wso2.carbon.identity.recovery.handler.IdentityUserMetadataMgtHandler; import org.wso2.carbon.identity.recovery.handler.MobileNumberVerificationHandler; @@ -64,12 +62,10 @@ import org.wso2.carbon.identity.recovery.handler.UserEmailVerificationHandler; import org.wso2.carbon.identity.recovery.handler.LiteUserRegistrationHandler; import org.wso2.carbon.identity.recovery.handler.UserSelfRegistrationHandler; -import org.wso2.carbon.identity.recovery.handler.request.PostAuthnMissingChallengeQuestionsHandler; import org.wso2.carbon.identity.recovery.internal.service.impl.password.PasswordRecoveryManagerImpl; import org.wso2.carbon.identity.recovery.internal.service.impl.username.UsernameRecoveryManagerImpl; import org.wso2.carbon.identity.recovery.listener.TenantManagementListener; import org.wso2.carbon.identity.recovery.password.NotificationPasswordRecoveryManager; -import org.wso2.carbon.identity.recovery.password.SecurityQuestionPasswordRecoveryManager; import org.wso2.carbon.identity.recovery.services.password.PasswordRecoveryManager; import org.wso2.carbon.identity.recovery.services.username.UsernameRecoveryManager; import org.wso2.carbon.identity.recovery.signup.UserSelfRegistrationManager; @@ -96,14 +92,10 @@ protected void activate(ComponentContext context) { BundleContext bundleContext = context.getBundleContext(); bundleContext.registerService(NotificationPasswordRecoveryManager.class.getName(), NotificationPasswordRecoveryManager.getInstance(), null); - bundleContext.registerService(SecurityQuestionPasswordRecoveryManager.class.getName(), - SecurityQuestionPasswordRecoveryManager.getInstance(), null); bundleContext.registerService(NotificationUsernameRecoveryManager.class.getName(), NotificationUsernameRecoveryManager.getInstance(), null); bundleContext.registerService(UserSelfRegistrationManager.class.getName(), UserSelfRegistrationManager .getInstance(), null); - bundleContext.registerService(ChallengeQuestionManager.class.getName(), ChallengeQuestionManager - .getInstance(), null); bundleContext.registerService(ResendConfirmationManager.class.getName(), ResendConfirmationManager .getInstance(), null); bundleContext.registerService(AbstractEventHandler.class.getName(), new @@ -140,13 +132,6 @@ protected void activate(ComponentContext context) { PasswordRecoveryManager passwordRecoveryManager = new PasswordRecoveryManagerImpl(); bundleContext.registerService(PasswordRecoveryManager.class.getName(), passwordRecoveryManager, null); - // Registering missing challenge question handler as a post authn handler - PostAuthenticationHandler postAuthnMissingChallengeQuestions = PostAuthnMissingChallengeQuestionsHandler - .getInstance(); - bundleContext.registerService(PostAuthenticationHandler.class.getName(), - postAuthnMissingChallengeQuestions, null); - bundleContext.registerService(AbstractEventHandler.class.getName(), - new ChallengeAnswerValidationHandler(), null); bundleContext.registerService(InputValidationManagementService.class.getName(), new InputValidationManagementServiceImpl(), null); } catch (Exception e) { @@ -155,16 +140,6 @@ protected void activate(ComponentContext context) { // register the tenant management listener TenantMgtListener tenantMgtListener = new TenantManagementListener(); context.getBundleContext().registerService(TenantMgtListener.class.getName(), tenantMgtListener, null); - // register default challenge questions - try { - if (log.isDebugEnabled()) { - log.debug("Loading default challenge questions for super tenant."); - } - loadDefaultChallengeQuestions(); - // new ChallengeQuestionManager().getAllChallengeQuestions("carbon.super", "lk_LK"); - } catch (IdentityRecoveryException e) { - log.error("Error persisting challenge question for super tenant.", e); - } } @Deactivate @@ -381,12 +356,6 @@ protected void unsetClaimMetaMgtService(ClaimMetadataManagementService claimMeta IdentityRecoveryServiceDataHolder.getInstance().setClaimMetadataManagementService(null); } - private void loadDefaultChallengeQuestions() throws IdentityRecoveryException { - - String tenantDomain = MultitenantConstants.SUPER_TENANT_DOMAIN_NAME; - ChallengeQuestionManager.getInstance().setDefaultChallengeQuestions(tenantDomain); - } - @Reference( name = "carbon.configuration.mgt.component", service = ConfigurationManager.class, diff --git a/components/org.wso2.carbon.identity.recovery/src/main/java/org/wso2/carbon/identity/recovery/internal/service/impl/password/PasswordRecoveryManagerImpl.java b/components/org.wso2.carbon.identity.recovery/src/main/java/org/wso2/carbon/identity/recovery/internal/service/impl/password/PasswordRecoveryManagerImpl.java index f9b2029b64..4bd35ccf77 100644 --- a/components/org.wso2.carbon.identity.recovery/src/main/java/org/wso2/carbon/identity/recovery/internal/service/impl/password/PasswordRecoveryManagerImpl.java +++ b/components/org.wso2.carbon.identity.recovery/src/main/java/org/wso2/carbon/identity/recovery/internal/service/impl/password/PasswordRecoveryManagerImpl.java @@ -28,7 +28,6 @@ import org.wso2.carbon.identity.core.util.IdentityUtil; import org.wso2.carbon.identity.event.IdentityEventException; import org.wso2.carbon.identity.governance.service.notification.NotificationChannels; -import org.wso2.carbon.identity.recovery.ChallengeQuestionManager; import org.wso2.carbon.identity.recovery.IdentityRecoveryClientException; import org.wso2.carbon.identity.recovery.IdentityRecoveryConstants; import org.wso2.carbon.identity.recovery.IdentityRecoveryException; @@ -91,50 +90,25 @@ public RecoveryInformationDTO initiate(Map claims, String tenant Map properties) throws IdentityRecoveryException { validateTenantDomain(tenantDomain); - UserAccountRecoveryManager userAccountRecoveryManager = UserAccountRecoveryManager.getInstance(); - boolean isQuestionBasedRecoveryEnabled = isQuestionBasedRecoveryEnabled(tenantDomain); boolean isNotificationBasedRecoveryEnabled = isNotificationBasedRecoveryEnabled(tenantDomain); + RecoveryInformationDTO recoveryInformationDTO = new RecoveryInformationDTO(); + recoveryInformationDTO.setNotificationBasedRecoveryEnabled(isNotificationBasedRecoveryEnabled); - if (!isNotificationBasedRecoveryEnabled && !isQuestionBasedRecoveryEnabled) { - if (log.isDebugEnabled()) { - log.debug("User password recovery is not enabled for the tenant: " + tenantDomain); - } - throw Utils.handleClientException( - IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_PASSWORD_RECOVERY_NOT_ENABLED, - null); + if (!isNotificationBasedRecoveryEnabled) { + return recoveryInformationDTO; } + + UserAccountRecoveryManager userAccountRecoveryManager = UserAccountRecoveryManager.getInstance(); // Get recovery channel information. RecoveryChannelInfoDTO recoveryChannelInfoDTO = userAccountRecoveryManager .retrieveUserRecoveryInformation(claims, tenantDomain, RecoveryScenarios.NOTIFICATION_BASED_PW_RECOVERY, properties); - RecoveryInformationDTO recoveryInformationDTO = new RecoveryInformationDTO(); String username = recoveryChannelInfoDTO.getUsername(); String recoveryFlowId = recoveryChannelInfoDTO.getRecoveryFlowId(); recoveryInformationDTO.setUsername(username); recoveryInformationDTO.setRecoveryFlowId(recoveryFlowId); // Do not add recovery channel information if Notification based recovery is not enabled. - recoveryInformationDTO.setNotificationBasedRecoveryEnabled(isNotificationBasedRecoveryEnabled); - if (isNotificationBasedRecoveryEnabled) { - recoveryInformationDTO.setRecoveryChannelInfoDTO(recoveryChannelInfoDTO); - } - - if (isSkipRecoveryWithChallengeQuestionsForInsufficientAnswersEnabled) { - recoveryInformationDTO.setQuestionBasedRecoveryAllowedForUser(isQuestionBasedRecoveryEnabled && - isMinNoOfRecoveryQuestionsAnswered(username, tenantDomain)); - } else { - recoveryInformationDTO.setQuestionBasedRecoveryAllowedForUser(isQuestionBasedRecoveryEnabled); - } - - // Check if question based password recovery is unlocked in per-user functionality locking mode. - if (isPerUserFunctionalityLockingEnabled) { - boolean isQuestionBasedRecoveryLocked = getFunctionalityStatusOfUser(tenantDomain, - recoveryChannelInfoDTO.getUsername(), - IdentityRecoveryConstants.FunctionalityTypes.FUNCTIONALITY_SECURITY_QUESTION_PW_RECOVERY - .getFunctionalityIdentifier()).getLockStatus(); - recoveryInformationDTO.setQuestionBasedRecoveryEnabled(!isQuestionBasedRecoveryLocked); - } else { - recoveryInformationDTO.setQuestionBasedRecoveryEnabled(isQuestionBasedRecoveryEnabled); - } + recoveryInformationDTO.setRecoveryChannelInfoDTO(recoveryChannelInfoDTO); recoveryInformationDTO.setNotificationBasedRecoveryEnabled(isNotificationBasedRecoveryEnabled); return recoveryInformationDTO; } @@ -861,36 +835,6 @@ private FunctionalityLockStatus getFunctionalityStatusOfUser(String tenantDomain } } - /** - * Checks if user has set answers for at least the minimum number of questions with answers required for password - * recovery. - * - * @param username The username of the user. - * @param tenantDomain The tenant domain of the user. - * @return True if expected number of challenge question answers have been set for the user. - * @throws IdentityRecoveryException Error while retrieving challenge question Ids for user. - */ - private boolean isMinNoOfRecoveryQuestionsAnswered(String username, String tenantDomain) throws - IdentityRecoveryException { - - User user = Utils.buildUser(username, tenantDomain); - ChallengeQuestionManager challengeQuestionManager = ChallengeQuestionManager.getInstance(); - String[] ids = challengeQuestionManager.getUserChallengeQuestionIds(user); - boolean isMinNoOfRecoveryQuestionsAnswered = false; - - if (ids != null) { - int minNoOfQuestionsToAnswer = Integer.parseInt(Utils.getRecoveryConfigs(IdentityRecoveryConstants - .ConnectorConfig.QUESTION_MIN_NO_ANSWER, tenantDomain)); - isMinNoOfRecoveryQuestionsAnswered = ids.length >= minNoOfQuestionsToAnswer; - if (isMinNoOfRecoveryQuestionsAnswered && log.isDebugEnabled()) { - log.debug(String.format("User: %s in tenant domain %s has set answers for at least the minimum number" + - " of questions with answers required for password recovery.", username, tenantDomain)); - } - } - - return isMinNoOfRecoveryQuestionsAnswered; - } - /** * This method is to validate the confirmation code when there's no recovery flow id. This is added as a fallback * logic to handle the already initiated email link based recovery flows and EXTERNAL channel based recovery flows diff --git a/components/org.wso2.carbon.identity.recovery/src/main/java/org/wso2/carbon/identity/recovery/listener/TenantManagementListener.java b/components/org.wso2.carbon.identity.recovery/src/main/java/org/wso2/carbon/identity/recovery/listener/TenantManagementListener.java index 05ed62de33..0552ebd4fa 100644 --- a/components/org.wso2.carbon.identity.recovery/src/main/java/org/wso2/carbon/identity/recovery/listener/TenantManagementListener.java +++ b/components/org.wso2.carbon.identity.recovery/src/main/java/org/wso2/carbon/identity/recovery/listener/TenantManagementListener.java @@ -19,7 +19,6 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.wso2.carbon.context.PrivilegedCarbonContext; -import org.wso2.carbon.identity.recovery.ChallengeQuestionManager; import org.wso2.carbon.identity.recovery.IdentityRecoveryException; import org.wso2.carbon.identity.recovery.store.JDBCRecoveryDataStore; import org.wso2.carbon.identity.recovery.store.UserRecoveryDataStore; @@ -42,18 +41,6 @@ public void onTenantCreate(TenantInfoBean tenantInfoBean) throws StratosExceptio PrivilegedCarbonContext.getThreadLocalCarbonContext().startTenantFlow(); PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantDomain(tenantDomain); PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantId(tenantInfoBean.getTenantId()); - - ChallengeQuestionManager questionManager = ChallengeQuestionManager.getInstance(); - try { - questionManager.setDefaultChallengeQuestions(tenantDomain); - if (log.isDebugEnabled()) { - log.debug("Default Challenge Questions persisted to the " + tenantDomain + " tenant"); - } - } catch (IdentityRecoveryException e) { - log.error("Error when trying to set default challenge question for tenant : " + tenantDomain, e); - } finally { - PrivilegedCarbonContext.endTenantFlow(); - } } @Override diff --git a/components/org.wso2.carbon.identity.recovery/src/main/java/org/wso2/carbon/identity/recovery/model/ChallengeQuestion.java b/components/org.wso2.carbon.identity.recovery/src/main/java/org/wso2/carbon/identity/recovery/model/ChallengeQuestion.java deleted file mode 100644 index 1cc24fe10c..0000000000 --- a/components/org.wso2.carbon.identity.recovery/src/main/java/org/wso2/carbon/identity/recovery/model/ChallengeQuestion.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright (c) 2014, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. - * - * WSO2 Inc. 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.recovery.model; - -/** - * encapsulates challenge questions data - */ -public class ChallengeQuestion { - - private String question; - - private String questionId; - - private String questionSetId; - - private String locale; - - public ChallengeQuestion() { - //default constructor - } - - public ChallengeQuestion(String questionSetId, String question) { - this.question = question; - this.questionSetId = questionSetId; - } - - public ChallengeQuestion(String questionSetId, String questionId, String question, String locale) { - this.questionSetId = questionSetId; - this.questionId = questionId; - this.question = question; - this.locale = locale; - } - - public String getQuestionId() { - return questionId; - } - - public void setQuestionId(String questionId) { - this.questionId = questionId; - } - - public String getQuestionSetId() { - return questionSetId; - } - - public void setQuestionSetId(String questionSetId) { - this.questionSetId = questionSetId; - } - - public String getQuestion() { - return question; - } - - public void setQuestion(String question) { - this.question = question; - } - - public String getLocale() { - return locale; - } - - public void setLocale(String locale) { - this.locale = locale; - } -} diff --git a/components/org.wso2.carbon.identity.recovery/src/main/java/org/wso2/carbon/identity/recovery/model/UserChallengeAnswer.java b/components/org.wso2.carbon.identity.recovery/src/main/java/org/wso2/carbon/identity/recovery/model/UserChallengeAnswer.java deleted file mode 100644 index e3181b748c..0000000000 --- a/components/org.wso2.carbon.identity.recovery/src/main/java/org/wso2/carbon/identity/recovery/model/UserChallengeAnswer.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (c) 2014, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. - * - * WSO2 Inc. 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.recovery.model; - -/** - * encapsulates challenge questions data - */ -public class UserChallengeAnswer { - - private ChallengeQuestion question; - - private String answer; - - public UserChallengeAnswer(ChallengeQuestion question, String answer) { - this.question = question; - this.answer = answer; - } - - public UserChallengeAnswer() { - //default constructor - } - - public ChallengeQuestion getQuestion() { - return question; - } - - public void setQuestion(ChallengeQuestion question) { - this.question = question; - } - - public String getAnswer() { - return answer; - } - - public void setAnswer(String answer) { - this.answer = answer; - } -} diff --git a/components/org.wso2.carbon.identity.recovery/src/main/java/org/wso2/carbon/identity/recovery/password/SecurityQuestionPasswordRecoveryManager.java b/components/org.wso2.carbon.identity.recovery/src/main/java/org/wso2/carbon/identity/recovery/password/SecurityQuestionPasswordRecoveryManager.java deleted file mode 100644 index cf56fd28b5..0000000000 --- a/components/org.wso2.carbon.identity.recovery/src/main/java/org/wso2/carbon/identity/recovery/password/SecurityQuestionPasswordRecoveryManager.java +++ /dev/null @@ -1,983 +0,0 @@ -/* - * - * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. - * - * WSO2 Inc. 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.recovery.password; - -import org.apache.commons.collections.MapUtils; -import org.apache.commons.lang.StringUtils; -import org.apache.commons.lang.math.NumberUtils; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.wso2.carbon.base.MultitenantConstants; -import org.wso2.carbon.identity.application.common.model.Property; -import org.wso2.carbon.identity.application.common.model.User; -import org.wso2.carbon.identity.base.IdentityException; -import org.wso2.carbon.identity.core.util.IdentityTenantUtil; -import org.wso2.carbon.identity.core.util.IdentityUtil; -import org.wso2.carbon.identity.event.IdentityEventConstants; -import org.wso2.carbon.identity.event.IdentityEventException; -import org.wso2.carbon.identity.event.event.Event; -import org.wso2.carbon.identity.recovery.ChallengeQuestionManager; -import org.wso2.carbon.identity.recovery.IdentityRecoveryClientException; -import org.wso2.carbon.identity.recovery.IdentityRecoveryConstants; -import org.wso2.carbon.identity.recovery.IdentityRecoveryException; -import org.wso2.carbon.identity.recovery.IdentityRecoveryServerException; -import org.wso2.carbon.identity.recovery.RecoveryScenarios; -import org.wso2.carbon.identity.recovery.RecoverySteps; -import org.wso2.carbon.identity.recovery.bean.ChallengeQuestionResponse; -import org.wso2.carbon.identity.recovery.bean.ChallengeQuestionsResponse; -import org.wso2.carbon.identity.recovery.handler.ConfigStoreFunctionalityLockPropertyHandler; -import org.wso2.carbon.identity.recovery.internal.IdentityRecoveryServiceDataHolder; -import org.wso2.carbon.identity.recovery.model.ChallengeQuestion; -import org.wso2.carbon.identity.recovery.model.UserChallengeAnswer; -import org.wso2.carbon.identity.recovery.model.UserRecoveryData; -import org.wso2.carbon.identity.recovery.store.JDBCRecoveryDataStore; -import org.wso2.carbon.identity.recovery.store.UserRecoveryDataStore; -import org.wso2.carbon.identity.recovery.util.Utils; -import org.wso2.carbon.identity.user.functionality.mgt.UserFunctionalityManager; -import org.wso2.carbon.identity.user.functionality.mgt.exception.UserFunctionalityManagementClientException; -import org.wso2.carbon.identity.user.functionality.mgt.exception.UserFunctionalityManagementException; -import org.wso2.carbon.identity.user.functionality.mgt.exception.UserFunctionalityManagementServerException; -import org.wso2.carbon.identity.user.functionality.mgt.model.FunctionalityLockStatus; -import org.wso2.carbon.user.api.UserStoreException; -import org.wso2.carbon.user.api.UserStoreManager; -import org.wso2.carbon.user.core.UserCoreConstants; -import org.wso2.carbon.user.core.UserRealm; -import org.wso2.carbon.user.core.service.RealmService; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Random; -import java.util.Set; -import java.util.UUID; - -/** - * Security Question Password Recovery Manager - */ -public class SecurityQuestionPasswordRecoveryManager { - - private static final Log log = LogFactory.getLog(SecurityQuestionPasswordRecoveryManager.class); - - private static final String PROPERTY_ACCOUNT_LOCK_ON_FAILURE = "account.lock.handler.lock.on.max.failed.attempts.enable"; - - private static final String PROPERTY_ACCOUNT_LOCK_ON_FAILURE_MAX = "account.lock.handler.On.Failure.Max.Attempts"; - - private static final String PROPERTY_ACCOUNT_LOCK_TIME = "account.lock.handler.Time"; - - private static final String PROPERTY_LOGIN_FAIL_TIMEOUT_RATIO = "account.lock.handler.login.fail.timeout.ratio"; - - private static final boolean isPerUserFunctionalityLockingEnabled = Utils.isPerUserFunctionalityLockingEnabled(); - - private static final boolean isDetailedErrorMessagesEnabled = Utils.isDetailedErrorResponseEnabled(); - - private static SecurityQuestionPasswordRecoveryManager instance = new SecurityQuestionPasswordRecoveryManager(); - - private SecurityQuestionPasswordRecoveryManager() { - - } - - public static SecurityQuestionPasswordRecoveryManager getInstance() { - return instance; - } - - public ChallengeQuestionResponse initiateUserChallengeQuestion(User user) throws IdentityRecoveryException { - - Utils.validateEmailUsername(user); - if (StringUtils.isBlank(user.getTenantDomain())) { - user.setTenantDomain(MultitenantConstants.SUPER_TENANT_DOMAIN_NAME); - log.info("initiateUserChallengeQuestion :Tenant domain is not in the request. set to default for user : " + - user.getUserName()); - } - - if (StringUtils.isBlank(user.getUserStoreDomain())) { - user.setUserStoreDomain(IdentityUtil.getPrimaryDomainName()); - log.info("initiateUserChallengeQuestion :User store domain is not in the request. set to default for user" + - " : " + user.getUserName()); - } - - - boolean isNotificationInternallyManaged = Boolean.parseBoolean(Utils.getRecoveryConfigs - (IdentityRecoveryConstants.ConnectorConfig.NOTIFICATION_INTERNALLY_MANAGE, user.getTenantDomain())); - - boolean isRecoveryEnable = Boolean.parseBoolean(Utils.getRecoveryConfigs(IdentityRecoveryConstants - .ConnectorConfig.QUESTION_BASED_PW_RECOVERY, user.getTenantDomain())); - if (!isRecoveryEnable) { - throw Utils.handleClientException(IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_QUESTION_BASED_RECOVERY_NOT_ENABLE, null); - } - - verifyUserExists(user); - validateFunctionalityForUser(user); - - UserRecoveryDataStore userRecoveryDataStore = JDBCRecoveryDataStore.getInstance(); - userRecoveryDataStore.invalidate(user); - - String challengeQuestionSeparator = IdentityUtil.getProperty(IdentityRecoveryConstants.ConnectorConfig - .QUESTION_CHALLENGE_SEPARATOR); - - if (StringUtils.isEmpty(challengeQuestionSeparator)) { - challengeQuestionSeparator = IdentityRecoveryConstants.DEFAULT_CHALLENGE_QUESTION_SEPARATOR; - } - - if (Utils.isAccountDisabled(user)) { - throw Utils.handleClientException( - IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_DISABLED_ACCOUNT, user.getUserName()); - } else if (Utils.isAccountLocked(user)) { - throw Utils.handleClientException( - IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_LOCKED_ACCOUNT, user.getUserName()); - } - - boolean isNotificationSendWhenInitiatingPWRecovery= Boolean.parseBoolean(Utils.getRecoveryConfigs - (IdentityRecoveryConstants.ConnectorConfig.NOTIFICATION_SEND_RECOVERY_SECURITY_START, user.getTenantDomain())); - - if (isNotificationInternallyManaged && isNotificationSendWhenInitiatingPWRecovery) { - try { - triggerNotification(user, IdentityRecoveryConstants.NOTIFICATION_TYPE_PASSWORD_RESET_INITIATE, null); - } catch (Exception e) { - log.warn("Error while sending password reset initiating notification to user :" + user.getUserName()); - } - } - - - int minNoOfQuestionsToAnswer = Integer.parseInt(Utils.getRecoveryConfigs(IdentityRecoveryConstants - .ConnectorConfig.QUESTION_MIN_NO_ANSWER, user.getTenantDomain())); - - ChallengeQuestionManager challengeQuestionManager = ChallengeQuestionManager.getInstance(); - String[] ids = challengeQuestionManager.getUserChallengeQuestionIds(user); - - if (ids == null || ids.length == 0) { - throw Utils.handleClientException(IdentityRecoveryConstants.ErrorMessages - .ERROR_CODE_CHALLENGE_QUESTION_NOT_FOUND, user.getUserName()); - } - - - if (ids.length > minNoOfQuestionsToAnswer) { - ids = getRandomQuestionIds(ids, minNoOfQuestionsToAnswer); - } - - String metaData = null; - - for (int i = 1; i < ids.length; i++) { - if (i == 1) { - metaData = ids[1]; - } else { - metaData = metaData + challengeQuestionSeparator + ids[i]; - } - } - - ChallengeQuestion userChallengeQuestion = challengeQuestionManager.getUserChallengeQuestion(user, ids[0]); - ChallengeQuestionResponse challengeQuestionResponse = new ChallengeQuestionResponse(userChallengeQuestion); - - String secretKey = UUID.randomUUID().toString(); - UserRecoveryData recoveryData = new UserRecoveryData(user, secretKey, RecoveryScenarios - .QUESTION_BASED_PWD_RECOVERY, RecoverySteps.VALIDATE_CHALLENGE_QUESTION); - recoveryData.setRemainingSetIds(metaData); - - challengeQuestionResponse.setCode(secretKey); - - if (ids.length > 1) { - challengeQuestionResponse.setStatus(IdentityRecoveryConstants.RECOVERY_STATUS_INCOMPLETE); - } - - userRecoveryDataStore.store(recoveryData); - return challengeQuestionResponse; - } - - private void validateFunctionalityForUser(User user) - throws IdentityRecoveryServerException, IdentityRecoveryClientException { - - if (isPerUserFunctionalityLockingEnabled) { - FunctionalityLockStatus functionalityLockStatus = getFunctionalityStatusOfUser(user, - IdentityRecoveryConstants.FunctionalityTypes.FUNCTIONALITY_SECURITY_QUESTION_PW_RECOVERY - .getFunctionalityIdentifier()); - - if (functionalityLockStatus.getLockStatus()) { - StringBuilder message = new StringBuilder( - IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_SECURITY_QUESTION_BASED_PWR_LOCKED - .getMessage()); - if (isDetailedErrorMessagesEnabled) { - message.append(": ").append(functionalityLockStatus.getLockReason()); - } - throw IdentityException.error(IdentityRecoveryClientException.class, - IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_SECURITY_QUESTION_BASED_PWR_LOCKED.getCode(), - message.toString()); - } - } - } - - public ChallengeQuestionsResponse initiateUserChallengeQuestionAtOnce(User user) throws IdentityRecoveryException { - String challengeQuestionSeparator = IdentityUtil.getProperty(IdentityRecoveryConstants.ConnectorConfig - .QUESTION_CHALLENGE_SEPARATOR); - - if (StringUtils.isEmpty(challengeQuestionSeparator)) { - challengeQuestionSeparator = IdentityRecoveryConstants.DEFAULT_CHALLENGE_QUESTION_SEPARATOR; - } - - if (StringUtils.isBlank(user.getTenantDomain())) { - user.setTenantDomain(MultitenantConstants.SUPER_TENANT_DOMAIN_NAME); - log.info("initiateUserChallengeQuestionAtOnce :Tenant domain is not in the request. set to default for user : " + - user.getUserName()); - } - - if (StringUtils.isBlank(user.getUserStoreDomain())) { - user.setUserStoreDomain(IdentityUtil.getPrimaryDomainName()); - log.info("initiateUserChallengeQuestionAtOnce :User store domain is not in the request. set to default for user" + - " : " + user.getUserName()); - } - - boolean isRecoveryEnable = Boolean.parseBoolean(Utils.getRecoveryConfigs(IdentityRecoveryConstants - .ConnectorConfig.QUESTION_BASED_PW_RECOVERY, user.getTenantDomain())); - if (!isRecoveryEnable) { - throw Utils.handleClientException(IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_QUESTION_BASED_RECOVERY_NOT_ENABLE, null); - } - - - boolean isNotificationInternallyManaged = Boolean.parseBoolean(Utils.getRecoveryConfigs - (IdentityRecoveryConstants.ConnectorConfig.NOTIFICATION_INTERNALLY_MANAGE, user.getTenantDomain())); - - - UserRecoveryDataStore userRecoveryDataStore = JDBCRecoveryDataStore.getInstance(); - userRecoveryDataStore.invalidate(user); - - verifyUserExists(user); - - if (Utils.isAccountDisabled(user)) { - throw Utils.handleClientException( - IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_DISABLED_ACCOUNT, null); - } else if (Utils.isAccountLocked(user)) { - throw Utils.handleClientException( - IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_LOCKED_ACCOUNT, null); - } - - boolean isNotificationSendWhenInitiatingPWRecovery= Boolean.parseBoolean(Utils.getRecoveryConfigs - (IdentityRecoveryConstants.ConnectorConfig.NOTIFICATION_SEND_RECOVERY_SECURITY_START, user.getTenantDomain())); - - if (isNotificationInternallyManaged && isNotificationSendWhenInitiatingPWRecovery) { - try { - triggerNotification(user, IdentityRecoveryConstants.NOTIFICATION_TYPE_PASSWORD_RESET_INITIATE, null); - } catch (Exception e) { - log.warn("Error while sending password reset initiating notification to user :" + user.getUserName()); - } - } - - int minNoOfQuestionsToAnswer = Integer.parseInt(Utils.getRecoveryConfigs(IdentityRecoveryConstants - .ConnectorConfig.QUESTION_MIN_NO_ANSWER, user.getTenantDomain())); - - ChallengeQuestionManager challengeQuestionManager = ChallengeQuestionManager.getInstance(); - String[] ids = challengeQuestionManager.getUserChallengeQuestionIds(user); - - if (ids == null || ids.length == 0) { - throw Utils.handleClientException(IdentityRecoveryConstants.ErrorMessages - .ERROR_CODE_CHALLENGE_QUESTION_NOT_FOUND, user.getUserName()); - } - - - if (ids.length > minNoOfQuestionsToAnswer) { - ids = getRandomQuestionIds(ids, minNoOfQuestionsToAnswer); - } - - ChallengeQuestion[] questions = new ChallengeQuestion[ids.length]; - - StringBuilder allChallengeQuestions = new StringBuilder(); - for (int i = 0; i < ids.length; i++) { - questions[i] = challengeQuestionManager.getUserChallengeQuestion(user, ids[i]); - if (i == 0) { - allChallengeQuestions.append(ids[0]); - } else { - allChallengeQuestions.append(challengeQuestionSeparator).append(ids[i]); - } - } - - ChallengeQuestionsResponse challengeQuestionResponse = new ChallengeQuestionsResponse(questions); - String secretKey = UUID.randomUUID().toString(); - UserRecoveryData recoveryData = new UserRecoveryData(user, secretKey, RecoveryScenarios - .QUESTION_BASED_PWD_RECOVERY, RecoverySteps.VALIDATE_ALL_CHALLENGE_QUESTION); - recoveryData.setRemainingSetIds(allChallengeQuestions.toString()); - - challengeQuestionResponse.setCode(secretKey); - userRecoveryDataStore.store(recoveryData); - return challengeQuestionResponse; - } - - - public ChallengeQuestionResponse validateUserChallengeQuestions(UserChallengeAnswer[] userChallengeAnswer, String - code, org.wso2.carbon.identity.recovery.model.Property[] properties) throws - IdentityRecoveryException { - - UserRecoveryDataStore userRecoveryDataStore = JDBCRecoveryDataStore.getInstance(); - UserRecoveryData userRecoveryData = userRecoveryDataStore.load(code); - //if return data from load, it means the code is validated. Otherwise it returns exceptions. - User user = userRecoveryData.getUser(); - - validateFunctionalityForUser(user); - - try { - boolean isRecoveryEnable = Boolean.parseBoolean(Utils.getRecoveryConfigs(IdentityRecoveryConstants - .ConnectorConfig.QUESTION_BASED_PW_RECOVERY, userRecoveryData.getUser().getTenantDomain())); - if (!isRecoveryEnable) { - throw Utils.handleClientException( - IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_QUESTION_BASED_RECOVERY_NOT_ENABLE, null); - } - - verifyUserExists(user); - if (Utils.isAccountDisabled(user)) { - throw Utils.handleClientException( - IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_DISABLED_ACCOUNT, user.getUserName()); - } else if (Utils.isAccountLocked(user)) { - throw Utils.handleClientException( - IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_LOCKED_ACCOUNT, user.getUserName()); - } - - if (userChallengeAnswer == null) { - String error = "Challenge answers cannot be found for user: " + userRecoveryData.getUser(); - throw Utils.handleClientException(IdentityRecoveryConstants.ErrorMessages - .ERROR_CODE_CHALLENGE_QUESTION_NOT_FOUND, error); - } - - String challengeQuestionSeparator = IdentityUtil.getProperty(IdentityRecoveryConstants.ConnectorConfig - .QUESTION_CHALLENGE_SEPARATOR); - - if (StringUtils.isEmpty(challengeQuestionSeparator)) { - challengeQuestionSeparator = IdentityRecoveryConstants.DEFAULT_CHALLENGE_QUESTION_SEPARATOR; - } - - if (RecoverySteps.VALIDATE_CHALLENGE_QUESTION.equals(userRecoveryData.getRecoveryStep())) { - - if (userChallengeAnswer.length > 1) { - throw Utils.handleClientException(IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_MULTIPLE_QUESTION_NOT_ALLOWED, null); - } - - ChallengeQuestionManager challengeQuestionManager = ChallengeQuestionManager.getInstance(); - boolean verified = challengeQuestionManager.verifyUserChallengeAnswer(userRecoveryData.getUser(), - userChallengeAnswer[0]); - if (verified) { - boolean resetFailedLoginCount = false; - userRecoveryDataStore.invalidate(code); - String remainingSetIds = userRecoveryData.getRemainingSetIds(); - ChallengeQuestionResponse challengeQuestionResponse = new ChallengeQuestionResponse(); - String secretKey = UUID.randomUUID().toString(); - challengeQuestionResponse.setCode(secretKey); - - UserRecoveryData recoveryData = new UserRecoveryData(userRecoveryData.getUser(), secretKey, RecoveryScenarios - .QUESTION_BASED_PWD_RECOVERY); - - if (StringUtils.isNotBlank(remainingSetIds)) { - String[] ids = remainingSetIds.split(challengeQuestionSeparator); - ChallengeQuestion challengeQuestion = challengeQuestionManager.getUserChallengeQuestion(userRecoveryData.getUser(), ids[0]); - challengeQuestionResponse.setQuestion(challengeQuestion); - recoveryData.setRecoveryStep(RecoverySteps.VALIDATE_CHALLENGE_QUESTION); - challengeQuestionResponse.setStatus(IdentityRecoveryConstants.RECOVERY_STATUS_INCOMPLETE); - - if (ids.length > 1) { - for (int i = 1; i < ids.length; i++) { - if (i == 1) { - remainingSetIds = ids[1]; - } else { - remainingSetIds = remainingSetIds + challengeQuestionSeparator + ids[i]; - } - } - recoveryData.setRemainingSetIds(remainingSetIds); - } - - } else { - resetFailedLoginCount = true; - recoveryData.setRecoveryStep(RecoverySteps.UPDATE_PASSWORD); - challengeQuestionResponse.setStatus(IdentityRecoveryConstants.RECOVERY_STATUS_COMPLETE); - } - - userRecoveryDataStore.store(recoveryData); - // Reset password recovery failed attempts - if (isPerUserFunctionalityLockingEnabled) { - resetRecoveryPasswordProperties(userRecoveryData.getUser(), resetFailedLoginCount); - } else { - resetRecoveryPasswordFailedAttempts(userRecoveryData.getUser(), resetFailedLoginCount); - } - - return challengeQuestionResponse; - } else { - throw Utils.handleClientException(IdentityRecoveryConstants.ErrorMessages - .ERROR_CODE_INVALID_ANSWER_FOR_SECURITY_QUESTION, null); - } - - } else if (RecoverySteps.VALIDATE_ALL_CHALLENGE_QUESTION.equals(userRecoveryData.getRecoveryStep())) { - String allChallengeQuestions = userRecoveryData.getRemainingSetIds(); - - if (StringUtils.isNotBlank(allChallengeQuestions)) { - String[] requestedQuestions = allChallengeQuestions.split(challengeQuestionSeparator); - - if (requestedQuestions.length != userChallengeAnswer.length) { - throw Utils.handleClientException(IdentityRecoveryConstants.ErrorMessages - .ERROR_CODE_NEED_TO_ANSWER_TO_REQUESTED_QUESTIONS, null); - } - validateQuestion(requestedQuestions, userChallengeAnswer); - //Validate whether user answered all the requested questions - - } else { - String error = "Could not find requested challenge questions for user: " + userRecoveryData - .getUser(); - throw Utils.handleClientException(IdentityRecoveryConstants.ErrorMessages - .ERROR_CODE_CHALLENGE_QUESTION_NOT_FOUND, error); - } - ChallengeQuestionManager challengeQuestionManager = ChallengeQuestionManager.getInstance(); - - for (int i = 0; i < userChallengeAnswer.length; i++) { - boolean verified = challengeQuestionManager.verifyUserChallengeAnswer(userRecoveryData.getUser(), - userChallengeAnswer[i]); - if (!verified) { -// handleAnswerVerificationFail(userRecoveryData.getUser()); - throw Utils.handleClientException(IdentityRecoveryConstants.ErrorMessages - .ERROR_CODE_INVALID_ANSWER_FOR_SECURITY_QUESTION, null); - } - } - - // Reset password recovery failed attempts - if (isPerUserFunctionalityLockingEnabled) { - resetRecoveryPasswordProperties(userRecoveryData.getUser(), true); - } else { - resetRecoveryPasswordFailedAttempts(userRecoveryData.getUser(), true); - } - - userRecoveryDataStore.invalidate(code); - ChallengeQuestionResponse challengeQuestionResponse = new ChallengeQuestionResponse(); - String secretKey = UUID.randomUUID().toString(); - challengeQuestionResponse.setCode(secretKey); - challengeQuestionResponse.setStatus(IdentityRecoveryConstants.RECOVERY_STATUS_COMPLETE); - UserRecoveryData recoveryData = - new UserRecoveryData(userRecoveryData.getUser(), secretKey, RecoveryScenarios - .QUESTION_BASED_PWD_RECOVERY); - - recoveryData.setRecoveryStep(RecoverySteps.UPDATE_PASSWORD); - - userRecoveryDataStore.store(recoveryData); - - return challengeQuestionResponse; - } else { - throw Utils.handleClientException(IdentityRecoveryConstants.ErrorMessages - .ERROR_CODE_INVALID_CODE, null); - } - } catch (IdentityRecoveryClientException e) { - if (isPerUserFunctionalityLockingEnabled) { - handleAnswerVerificationFailInFunctionalityLockMode(userRecoveryData.getUser()); - throw e; - } - handleAnswerVerificationFail(userRecoveryData.getUser()); - throw e; - } - } - - private void validateQuestion(String[] requestedQuestions, UserChallengeAnswer[] userChallengeAnswer) - throws IdentityRecoveryException { - List userChallengeIds = new ArrayList<>(); - for (int i = 0; i < userChallengeAnswer.length; i++) { - userChallengeIds.add(userChallengeAnswer[i].getQuestion().getQuestionSetId().toLowerCase()); - } - - for (int i = 0; i < requestedQuestions.length; i++) { - if (!userChallengeIds.contains(requestedQuestions[i].toLowerCase())) { - throw Utils.handleClientException(IdentityRecoveryConstants.ErrorMessages - .ERROR_CODE_NEED_TO_ANSWER_TO_REQUESTED_QUESTIONS, null); - } - } - } - - - private static String[] getRandomQuestionIds(String[] allQuesitons, int minNoOfQuestionsToAnswser) { - ArrayList remainingQuestions = new ArrayList(Arrays.asList(allQuesitons)); - ArrayList selectedQuestions = new ArrayList(); - - for (int i = 0; i < minNoOfQuestionsToAnswser; i++) { - int random = new Random().nextInt(remainingQuestions.size()); - selectedQuestions.add(i, remainingQuestions.get(random)); - remainingQuestions.remove(random); - } - return (String[]) selectedQuestions.toArray(new String[selectedQuestions.size()]); - } - - private void triggerNotification(User user, String type, String code) throws IdentityRecoveryException { - - String eventName = IdentityEventConstants.Event.TRIGGER_NOTIFICATION; - - HashMap properties = new HashMap<>(); - properties.put(IdentityEventConstants.EventProperty.USER_NAME, user.getUserName()); - properties.put(IdentityEventConstants.EventProperty.TENANT_DOMAIN, user.getTenantDomain()); - properties.put(IdentityEventConstants.EventProperty.USER_STORE_DOMAIN, user.getUserStoreDomain()); - - if (StringUtils.isNotBlank(code)) { - properties.put(IdentityRecoveryConstants.CONFIRMATION_CODE, code); - } - properties.put(IdentityRecoveryConstants.TEMPLATE_TYPE, type); - Event identityMgtEvent = new Event(eventName, properties); - try { - IdentityRecoveryServiceDataHolder.getInstance().getIdentityEventService().handleEvent(identityMgtEvent); - } catch (IdentityEventException e) { - throw Utils.handleServerException(IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_TRIGGER_NOTIFICATION, user - .getUserName(), e); - } - } - - private Property[] getConnectorConfigs(String tenantDomain) throws IdentityRecoveryException { - - Property[] connectorConfigs; - try { - connectorConfigs = IdentityRecoveryServiceDataHolder.getInstance() - .getIdentityGovernanceService() - .getConfiguration( - new String[]{PROPERTY_ACCOUNT_LOCK_ON_FAILURE, PROPERTY_ACCOUNT_LOCK_ON_FAILURE_MAX, - PROPERTY_ACCOUNT_LOCK_TIME, PROPERTY_LOGIN_FAIL_TIMEOUT_RATIO}, tenantDomain); - } catch (Exception e) { - throw Utils.handleServerException(IdentityRecoveryConstants.ErrorMessages - .ERROR_CODE_FAILED_TO_LOAD_GOV_CONFIGS, null, e); - } - return connectorConfigs; - } - - private void resetRecoveryPasswordFailedAttempts(User user, boolean resetFailedLoginLockOutCount) - throws IdentityRecoveryException { - - Property[] connectorConfigs = getConnectorConfigs(user.getTenantDomain()); - - for (Property connectorConfig : connectorConfigs) { - if ((PROPERTY_ACCOUNT_LOCK_ON_FAILURE.equals(connectorConfig.getName())) && - !Boolean.parseBoolean(connectorConfig.getValue())) { - return; - } - } - - int tenantId = IdentityTenantUtil.getTenantId(user.getTenantDomain()); - - RealmService realmService = IdentityRecoveryServiceDataHolder.getInstance().getRealmService(); - UserRealm userRealm; - try { - userRealm = (UserRealm) realmService.getTenantUserRealm(tenantId); - } catch (UserStoreException e) { - throw Utils.handleServerException(IdentityRecoveryConstants.ErrorMessages - .ERROR_CODE_FAILED_TO_LOAD_REALM_SERVICE, user.getTenantDomain(), e); - } - - org.wso2.carbon.user.core.UserStoreManager userStoreManager; - try { - userStoreManager = userRealm.getUserStoreManager(); - } catch (UserStoreException e) { - throw Utils.handleServerException(IdentityRecoveryConstants.ErrorMessages - .ERROR_CODE_FAILED_TO_LOAD_USER_STORE_MANAGER, null, e); - } - - Map updatedClaims = new HashMap<>(); - if (resetFailedLoginLockOutCount) { - updatedClaims.put(IdentityRecoveryConstants.FAILED_LOGIN_LOCKOUT_COUNT_CLAIM, "0"); - } - updatedClaims.put(IdentityRecoveryConstants.PASSWORD_RESET_FAIL_ATTEMPTS_CLAIM, "0"); - try { - userStoreManager.setUserClaimValues(IdentityUtil.addDomainToName(user.getUserName(), - user.getUserStoreDomain()), updatedClaims, UserCoreConstants.DEFAULT_PROFILE); - } catch (org.wso2.carbon.user.core.UserStoreException e) { - throw Utils.handleServerException(IdentityRecoveryConstants.ErrorMessages - .ERROR_CODE_FAILED_TO_UPDATE_USER_CLAIMS, null, e); - } - } - - private void resetRecoveryPasswordProperties(User user, boolean resetFailedLoginLockOutCount) - throws IdentityRecoveryException { - - Property[] connectorConfigs = getConnectorConfigs(user.getTenantDomain()); - - for (Property connectorConfig : connectorConfigs) { - if ((PROPERTY_ACCOUNT_LOCK_ON_FAILURE.equals(connectorConfig.getName())) && - !Boolean.parseBoolean(connectorConfig.getValue())) { - return; - } - } - int tenantId = IdentityTenantUtil.getTenantId(user.getTenantDomain()); - String userId = Utils.getUserId(user.getUserName(), tenantId); - UserFunctionalityManager userFunctionalityManager = - IdentityRecoveryServiceDataHolder.getInstance().getUserFunctionalityManagerService(); - - if (resetFailedLoginLockOutCount) { - try { - userFunctionalityManager.unlock(userId, tenantId, - IdentityRecoveryConstants.FunctionalityTypes.FUNCTIONALITY_SECURITY_QUESTION_PW_RECOVERY - .getFunctionalityIdentifier()); - userFunctionalityManager.deleteAllPropertiesForUser(userId, tenantId, - IdentityRecoveryConstants.FunctionalityTypes.FUNCTIONALITY_SECURITY_QUESTION_PW_RECOVERY - .getFunctionalityIdentifier()); - } catch (UserFunctionalityManagementException e) { - throw Utils.handleFunctionalityLockMgtServerException( - IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_FAILED_TO_UNLOCK_FUNCTIONALITY_FOR_USER, userId, - tenantId, IdentityRecoveryConstants.FunctionalityTypes. - FUNCTIONALITY_SECURITY_QUESTION_PW_RECOVERY.getFunctionalityIdentifier(), - isDetailedErrorMessagesEnabled); - } - } else { - try { - Map propertiesToUpdate = new HashMap(); - propertiesToUpdate.put(IdentityRecoveryConstants.FUNCTION_FAILED_ATTEMPTS_PROPERTY, "0"); - userFunctionalityManager.setProperties(userId, tenantId, - IdentityRecoveryConstants.FunctionalityTypes.FUNCTIONALITY_SECURITY_QUESTION_PW_RECOVERY - .getFunctionalityIdentifier(), propertiesToUpdate); - } catch (UserFunctionalityManagementException e) { - throw Utils.handleFunctionalityLockMgtServerException( - IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_FAILED_TO_UPDATE_PROPERTIES_FOR_FUNCTIONALITY, - userId, tenantId, IdentityRecoveryConstants. - FunctionalityTypes.FUNCTIONALITY_SECURITY_QUESTION_PW_RECOVERY.getFunctionalityIdentifier(), - isDetailedErrorMessagesEnabled); - } - } - } - - private void handleAnswerVerificationFail(User user) throws IdentityRecoveryException { - - Property[] connectorConfigs = getConnectorConfigs(user.getTenantDomain()); - - int maxAttempts = 0; - long unlockTimePropertyValue = 0; - double unlockTimeRatio = 1; - for (Property connectorConfig : connectorConfigs) { - if ((PROPERTY_ACCOUNT_LOCK_ON_FAILURE.equals(connectorConfig.getName())) && - !Boolean.parseBoolean(connectorConfig.getValue())) { - return; - } else if (PROPERTY_ACCOUNT_LOCK_ON_FAILURE_MAX.equals(connectorConfig.getName()) - && NumberUtils.isNumber(connectorConfig.getValue())) { - maxAttempts = Integer.parseInt(connectorConfig.getValue()); - } else if (PROPERTY_ACCOUNT_LOCK_TIME.equals(connectorConfig.getName()) - && NumberUtils.isNumber(connectorConfig.getValue())) { - unlockTimePropertyValue = Integer.parseInt(connectorConfig.getValue()); - } else if (PROPERTY_LOGIN_FAIL_TIMEOUT_RATIO.equals(connectorConfig.getName()) - && NumberUtils.isNumber(connectorConfig.getValue())) { - double value = Double.parseDouble(connectorConfig.getValue()); - if (value > 0) { - unlockTimeRatio = value; - } - } - } - - int tenantId = IdentityTenantUtil.getTenantId(user.getTenantDomain()); - - RealmService realmService = IdentityRecoveryServiceDataHolder.getInstance().getRealmService(); - UserRealm userRealm; - try { - userRealm = (UserRealm) realmService.getTenantUserRealm(tenantId); - } catch (UserStoreException e) { - throw Utils.handleServerException(IdentityRecoveryConstants.ErrorMessages - .ERROR_CODE_FAILED_TO_LOAD_REALM_SERVICE, user.getTenantDomain(), e); - } - - org.wso2.carbon.user.core.UserStoreManager userStoreManager; - try { - userStoreManager = userRealm.getUserStoreManager(); - } catch (UserStoreException e) { - throw Utils.handleServerException(IdentityRecoveryConstants.ErrorMessages - .ERROR_CODE_FAILED_TO_LOAD_USER_STORE_MANAGER, null, e); - } - - if (Utils.isAccountLocked(user)) { - return; - } - - Map claimValues; - try { - claimValues = userStoreManager.getUserClaimValues(IdentityUtil.addDomainToName(user.getUserName(), user - .getUserStoreDomain()), new String[]{ - IdentityRecoveryConstants.PASSWORD_RESET_FAIL_ATTEMPTS_CLAIM, - IdentityRecoveryConstants.FAILED_LOGIN_LOCKOUT_COUNT_CLAIM}, - UserCoreConstants.DEFAULT_PROFILE); - } catch (org.wso2.carbon.user.core.UserStoreException e) { - throw Utils.handleServerException(IdentityRecoveryConstants.ErrorMessages - .ERROR_CODE_FAILED_TO_LOAD_USER_CLAIMS, null, e); - } - - int currentAttempts = 0; - if (NumberUtils.isNumber(claimValues.get(IdentityRecoveryConstants.PASSWORD_RESET_FAIL_ATTEMPTS_CLAIM))) { - currentAttempts = Integer.parseInt(claimValues.get(IdentityRecoveryConstants - .PASSWORD_RESET_FAIL_ATTEMPTS_CLAIM)); - } - - int failedLoginLockoutCountValue = 0; - if (NumberUtils.isNumber(claimValues.get(IdentityRecoveryConstants.FAILED_LOGIN_LOCKOUT_COUNT_CLAIM))) { - failedLoginLockoutCountValue = - Integer.parseInt(claimValues.get(IdentityRecoveryConstants.FAILED_LOGIN_LOCKOUT_COUNT_CLAIM)); - } - - Map updatedClaims = new HashMap<>(); - if ((currentAttempts + 1) >= maxAttempts) { - // Calculate the incremental unlock-time-interval in milli seconds. - unlockTimePropertyValue = (long) (unlockTimePropertyValue * 1000 * 60 * Math.pow - (unlockTimeRatio, failedLoginLockoutCountValue)); - // Calculate unlock-time by adding current-time and unlock-time-interval in milli seconds. - long unlockTime = System.currentTimeMillis() + unlockTimePropertyValue; - updatedClaims.put(IdentityRecoveryConstants.ACCOUNT_LOCKED_CLAIM, Boolean.TRUE.toString()); - updatedClaims.put(IdentityRecoveryConstants.PASSWORD_RESET_FAIL_ATTEMPTS_CLAIM, "0"); - updatedClaims.put(IdentityRecoveryConstants.ACCOUNT_UNLOCK_TIME_CLAIM, String.valueOf(unlockTime)); - updatedClaims.put(IdentityRecoveryConstants.FAILED_LOGIN_LOCKOUT_COUNT_CLAIM, - String.valueOf(failedLoginLockoutCountValue + 1)); - try { - userStoreManager.setUserClaimValues(IdentityUtil.addDomainToName(user.getUserName(), - user.getUserStoreDomain()), updatedClaims, UserCoreConstants.DEFAULT_PROFILE); - throw Utils.handleClientException(IdentityRecoveryConstants.ErrorMessages - .ERROR_CODE_LOCKED_ACCOUNT, IdentityUtil.addDomainToName(user.getUserName(), - user.getUserStoreDomain())); - } catch (org.wso2.carbon.user.core.UserStoreException e) { - throw Utils.handleServerException(IdentityRecoveryConstants.ErrorMessages - .ERROR_CODE_FAILED_TO_UPDATE_USER_CLAIMS, null, e); - } - } else { - updatedClaims.put(IdentityRecoveryConstants.PASSWORD_RESET_FAIL_ATTEMPTS_CLAIM, - String.valueOf(currentAttempts + 1)); - try { - userStoreManager.setUserClaimValues(IdentityUtil.addDomainToName(user.getUserName(), - user.getUserStoreDomain()), updatedClaims, UserCoreConstants.DEFAULT_PROFILE); - } catch (org.wso2.carbon.user.core.UserStoreException e) { - throw Utils.handleServerException(IdentityRecoveryConstants.ErrorMessages - .ERROR_CODE_FAILED_TO_UPDATE_USER_CLAIMS, null, e); - } - } - } - - private void handleAnswerVerificationFailInFunctionalityLockMode(User user) throws IdentityRecoveryException { - - if (Utils.isAccountLocked(user)) { - return; - } - - int tenantId = IdentityTenantUtil.getTenantId(user.getTenantDomain()); - String userId = Utils.getUserId(user.getUserName(), tenantId); - - Map configStoreProperties = - ConfigStoreFunctionalityLockPropertyHandler - .getInstance().getConfigStoreProperties(user.getTenantDomain(), - IdentityRecoveryConstants.FunctionalityTypes.FUNCTIONALITY_SECURITY_QUESTION_PW_RECOVERY - .getFunctionalityIdentifier()); - - validateUserFunctionalityProperties(configStoreProperties); - - int maxAttempts = - Integer.parseInt(configStoreProperties.get(IdentityRecoveryConstants.FUNCTION_MAX_ATTEMPTS_PROPERTY)); - long unlockTimePropertyValue = - Integer.parseInt(configStoreProperties.get(IdentityRecoveryConstants.FUNCTION_LOCKOUT_TIME_PROPERTY)); - double unlockTimeRatio = - Double.parseDouble( - configStoreProperties.get(IdentityRecoveryConstants.FUNCTION_LOGIN_FAIL_TIMEOUT_RATIO_PROPERTY)); - - int currentAttempts = 0; - int failedLoginLockoutCountValue = 0; - UserFunctionalityManager userFunctionalityManager = - IdentityRecoveryServiceDataHolder.getInstance().getUserFunctionalityManagerService(); - Map functionalityLockProperties; - try { - functionalityLockProperties = userFunctionalityManager.getProperties(userId, tenantId, - IdentityRecoveryConstants.FunctionalityTypes.FUNCTIONALITY_SECURITY_QUESTION_PW_RECOVERY - .getFunctionalityIdentifier()); - } catch (UserFunctionalityManagementException e) { - throw Utils.handleFunctionalityLockMgtServerException( - IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_FAILED_TO_GET_PROPERTIES_FOR_FUNCTIONALITY, - userId, tenantId, IdentityRecoveryConstants.FunctionalityTypes. - FUNCTIONALITY_SECURITY_QUESTION_PW_RECOVERY.getFunctionalityIdentifier(), - isDetailedErrorMessagesEnabled); - } - if (functionalityLockProperties.isEmpty()) { - functionalityLockProperties.put(IdentityRecoveryConstants.FUNCTION_LOCKOUT_COUNT_PROPERTY, - String.valueOf(failedLoginLockoutCountValue)); - functionalityLockProperties - .put(IdentityRecoveryConstants.FUNCTION_FAILED_ATTEMPTS_PROPERTY, String.valueOf(currentAttempts)); - functionalityLockProperties - .put(IdentityRecoveryConstants.FUNCTION_MAX_ATTEMPTS_PROPERTY, String.valueOf(maxAttempts)); - try { - userFunctionalityManager.setProperties(userId, tenantId, - IdentityRecoveryConstants.FunctionalityTypes.FUNCTIONALITY_SECURITY_QUESTION_PW_RECOVERY - .getFunctionalityIdentifier(), functionalityLockProperties); - } catch (UserFunctionalityManagementException e) { - throw Utils.handleFunctionalityLockMgtServerException( - IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_FAILED_TO_ADD_PROPERTIES_FOR_FUNCTIONALITY, - userId, tenantId, IdentityRecoveryConstants.FunctionalityTypes. - FUNCTIONALITY_SECURITY_QUESTION_PW_RECOVERY.getFunctionalityIdentifier(), - isDetailedErrorMessagesEnabled); - } - } else { - if (NumberUtils.isNumber( - functionalityLockProperties.get(IdentityRecoveryConstants.FUNCTION_LOCKOUT_COUNT_PROPERTY))) { - failedLoginLockoutCountValue = Integer.parseInt( - functionalityLockProperties.get(IdentityRecoveryConstants.FUNCTION_LOCKOUT_COUNT_PROPERTY)); - } - if (NumberUtils.isNumber( - functionalityLockProperties.get(IdentityRecoveryConstants.FUNCTION_FAILED_ATTEMPTS_PROPERTY))) { - currentAttempts = Integer.parseInt( - functionalityLockProperties.get(IdentityRecoveryConstants.FUNCTION_FAILED_ATTEMPTS_PROPERTY)); - } - } - - Map updatedFunctionalityLockProperties = new HashMap<>(); - if ((currentAttempts + 1) >= maxAttempts) { - // Calculate the incremental unlock-time-interval in milli seconds. - unlockTimePropertyValue = (long) (unlockTimePropertyValue * 1000 * 60 * Math.pow - (unlockTimeRatio, failedLoginLockoutCountValue)); - try { - updatedFunctionalityLockProperties.put(IdentityRecoveryConstants.FUNCTION_FAILED_ATTEMPTS_PROPERTY, "0"); - updatedFunctionalityLockProperties.put(IdentityRecoveryConstants.FUNCTION_LOCKOUT_COUNT_PROPERTY, - String.valueOf(failedLoginLockoutCountValue + 1)); - userFunctionalityManager.lock(userId, tenantId, - IdentityRecoveryConstants.FunctionalityTypes.FUNCTIONALITY_SECURITY_QUESTION_PW_RECOVERY - .getFunctionalityIdentifier(), unlockTimePropertyValue, - IdentityRecoveryConstants.RecoveryLockReasons.PWD_RECOVERY_MAX_ATTEMPTS_EXCEEDED - .getFunctionalityLockCode(), - IdentityRecoveryConstants.RecoveryLockReasons.PWD_RECOVERY_MAX_ATTEMPTS_EXCEEDED - .getFunctionalityLockReason()); - userFunctionalityManager.setProperties(userId, tenantId, - IdentityRecoveryConstants.FunctionalityTypes.FUNCTIONALITY_SECURITY_QUESTION_PW_RECOVERY - .getFunctionalityIdentifier(), updatedFunctionalityLockProperties); - } catch (UserFunctionalityManagementServerException e) { - throw Utils.handleFunctionalityLockMgtServerException( - IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_FAILED_TO_LOCK_FUNCTIONALITY_FOR_USER, userId, - tenantId, IdentityRecoveryConstants.FunctionalityTypes.FUNCTIONALITY_SECURITY_QUESTION_PW_RECOVERY - .getFunctionalityIdentifier(), isDetailedErrorMessagesEnabled); - } catch (UserFunctionalityManagementException e) { - e.printStackTrace(); - } - StringBuilder message = new StringBuilder( - IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_SECURITY_QUESTION_BASED_PWR_LOCKED - .getMessage()); - if (isDetailedErrorMessagesEnabled) { - message.append(": ") - .append(IdentityRecoveryConstants.RecoveryLockReasons.PWD_RECOVERY_MAX_ATTEMPTS_EXCEEDED - .getFunctionalityLockReason()); - } - throw IdentityException.error(IdentityRecoveryClientException.class, - IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_SECURITY_QUESTION_BASED_PWR_LOCKED - .getCode(), message.toString()); - - } else { - try { - Map propertiesToUpdate = new HashMap<>(); - propertiesToUpdate.put(IdentityRecoveryConstants.FUNCTION_FAILED_ATTEMPTS_PROPERTY, - String.valueOf(currentAttempts + 1)); - userFunctionalityManager.setProperties(userId, tenantId, - IdentityRecoveryConstants.FunctionalityTypes.FUNCTIONALITY_SECURITY_QUESTION_PW_RECOVERY - .getFunctionalityIdentifier(), propertiesToUpdate); - } catch (UserFunctionalityManagementException e) { - throw Utils.handleFunctionalityLockMgtServerException( - IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_FAILED_TO_UPDATE_PROPERTIES_FOR_FUNCTIONALITY, - userId, tenantId, IdentityRecoveryConstants.FunctionalityTypes. - FUNCTIONALITY_SECURITY_QUESTION_PW_RECOVERY.getFunctionalityIdentifier(), - isDetailedErrorMessagesEnabled); - } - } - } - - private void validateUserFunctionalityProperties(Map configStoreProperties) { - - Set propertyNames = new HashSet<>(Arrays.asList(IdentityRecoveryConstants.FUNCTION_MAX_ATTEMPTS_PROPERTY, - IdentityRecoveryConstants.FUNCTION_LOCKOUT_TIME_PROPERTY, - IdentityRecoveryConstants.FUNCTION_LOGIN_FAIL_TIMEOUT_RATIO_PROPERTY)); - - if (MapUtils.isEmpty(configStoreProperties)) { - throw new UnsupportedOperationException("User Functionality properties are not configured."); - } - if (configStoreProperties.keySet().equals(propertyNames)) { - if (!NumberUtils - .isNumber(configStoreProperties.get(IdentityRecoveryConstants.FUNCTION_MAX_ATTEMPTS_PROPERTY))) { - throw new UnsupportedOperationException("User Functionality properties are not configured."); - } - if (!NumberUtils - .isNumber(configStoreProperties.get(IdentityRecoveryConstants.FUNCTION_LOCKOUT_TIME_PROPERTY))) { - throw new UnsupportedOperationException("User Functionality properties are not configured."); - } - if (!NumberUtils.isNumber( - configStoreProperties.get(IdentityRecoveryConstants.FUNCTION_LOGIN_FAIL_TIMEOUT_RATIO_PROPERTY))) { - throw new UnsupportedOperationException("User Functionality properties are not configured."); - } - } else { - throw new UnsupportedOperationException("User Functionality properties are not configured."); - } - } - - private void verifyUserExists(User user) throws IdentityRecoveryClientException, IdentityRecoveryServerException { - - UserStoreManager userStoreManager; - try { - int tenantId = IdentityTenantUtil.getTenantId(user.getTenantDomain()); - userStoreManager = IdentityRecoveryServiceDataHolder.getInstance().getRealmService(). - getTenantUserRealm(tenantId).getUserStoreManager(); - String domainQualifiedUsername = - IdentityUtil.addDomainToName(user.getUserName(), user.getUserStoreDomain()); - - if (!userStoreManager.isExistingUser(domainQualifiedUsername)) { - if (log.isDebugEnabled()) { - log.debug("No user found for recovery with username: " + user.toFullQualifiedUsername()); - } - boolean notifyUserExistence = Boolean.parseBoolean(IdentityUtil.getProperty( - IdentityRecoveryConstants.ConnectorConfig.NOTIFY_USER_EXISTENCE)); - if (notifyUserExistence) { - throw Utils.handleClientException(IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_INVALID_USER, - domainQualifiedUsername); - } else { - throw Utils.handleClientException(IdentityRecoveryConstants.ErrorMessages - .ERROR_CODE_CHALLENGE_QUESTION_NOT_FOUND, user.getUserName()); - } - } - - } catch (UserStoreException e) { - throw Utils.handleServerException(IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_UNEXPECTED, null); - } - } - - /** - * Get the lock status of a functionality given the tenant domain, user name and the functionality identifier. - * - * @param user User. - * @param functionalityIdentifier Identifier of the the functionality. - * @return The status of the functionality, {@link FunctionalityLockStatus}. - */ - private FunctionalityLockStatus getFunctionalityStatusOfUser(User user, String functionalityIdentifier) - throws IdentityRecoveryServerException { - - int tenantId = IdentityTenantUtil.getTenantId(user.getTenantDomain()); - String userId = Utils.getUserId(user.getUserName(), tenantId); - - UserFunctionalityManager userFunctionalityManager = - IdentityRecoveryServiceDataHolder.getInstance().getUserFunctionalityManagerService(); - - try { - return userFunctionalityManager.getLockStatus(userId, tenantId, functionalityIdentifier); - } catch (UserFunctionalityManagementException e) { - String mappedErrorCode = - Utils.prependOperationScenarioToErrorCode( - IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_FAILED_TO_GET_LOCK_STATUS_FOR_FUNCTIONALITY - .getCode(), IdentityRecoveryConstants.PASSWORD_RECOVERY_SCENARIO); - StringBuilder message = - new StringBuilder( - IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_FAILED_TO_GET_LOCK_STATUS_FOR_FUNCTIONALITY - .getMessage()); - if (isDetailedErrorMessagesEnabled) { - message.append(String.format("functionalityIdentifier: %s for %s.", - IdentityRecoveryConstants.FunctionalityTypes.FUNCTIONALITY_SECURITY_QUESTION_PW_RECOVERY - .getFunctionalityIdentifier(), user.getUserName())); - } - String errorMessage = "Error occurred while getting functionality status of user."; - if (e instanceof UserFunctionalityManagementClientException) { - if (log.isDebugEnabled()) { - log.debug(errorMessage, e); - } - } else { - log.error(errorMessage, e); - } - throw Utils.handleServerException(mappedErrorCode, message.toString(), null); - } - } -} diff --git a/components/org.wso2.carbon.identity.recovery/src/main/java/org/wso2/carbon/identity/recovery/services/ChallengeQuestionManagementAdminService.java b/components/org.wso2.carbon.identity.recovery/src/main/java/org/wso2/carbon/identity/recovery/services/ChallengeQuestionManagementAdminService.java deleted file mode 100644 index c116ae0a9b..0000000000 --- a/components/org.wso2.carbon.identity.recovery/src/main/java/org/wso2/carbon/identity/recovery/services/ChallengeQuestionManagementAdminService.java +++ /dev/null @@ -1,327 +0,0 @@ -/* - * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. - * - * Licensed 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.recovery.services; - -import org.apache.commons.lang.ArrayUtils; -import org.apache.commons.lang.StringUtils; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.wso2.carbon.CarbonConstants; -import org.wso2.carbon.context.CarbonContext; -import org.wso2.carbon.identity.application.common.model.User; -import org.wso2.carbon.identity.base.IdentityException; -import org.wso2.carbon.identity.core.util.IdentityTenantUtil; -import org.wso2.carbon.identity.core.util.IdentityUtil; -import org.wso2.carbon.identity.recovery.ChallengeQuestionManager; -import org.wso2.carbon.identity.recovery.IdentityRecoveryClientException; -import org.wso2.carbon.identity.recovery.IdentityRecoveryException; -import org.wso2.carbon.identity.recovery.IdentityRecoveryServerException; -import org.wso2.carbon.identity.recovery.internal.IdentityRecoveryServiceDataHolder; -import org.wso2.carbon.identity.recovery.model.ChallengeQuestion; -import org.wso2.carbon.identity.recovery.model.UserChallengeAnswer; -import org.wso2.carbon.user.api.AuthorizationManager; -import org.wso2.carbon.user.api.UserStoreException; -import org.wso2.carbon.user.core.UserCoreConstants; -import org.wso2.carbon.user.core.util.UserCoreUtil; -import org.wso2.carbon.utils.multitenancy.MultitenantUtils; - -import java.util.List; - -/** - * Admin Service class to carry out operations related to challenge questions management. - */ -public class ChallengeQuestionManagementAdminService { - - private static final Log log = LogFactory.getLog(ChallengeQuestionManagementAdminService.class); - private ChallengeQuestionManager questionManager = ChallengeQuestionManager.getInstance(); - - /** - * Get all challenge questions registered for a tenant. - * - * @param tenantDomain - * @return - * @throws IdentityRecoveryException - */ - public ChallengeQuestion[] getChallengeQuestionsOfTenant(String tenantDomain) throws IdentityRecoveryException { - - List challengeQuestionList; - checkCrossTenantAccess(tenantDomain); - try { - challengeQuestionList = questionManager.getAllChallengeQuestions(tenantDomain); - return challengeQuestionList.toArray(new ChallengeQuestion[challengeQuestionList.size()]); - } catch (IdentityRecoveryException e) { - String errorMgs = "Error loading challenge questions for tenant : %s."; - log.error(String.format(errorMgs, tenantDomain), e); - throw new IdentityRecoveryException(String.format(errorMgs, tenantDomain), e); - } - } - - /** - * Get all challenge questions applicable for a user based on his locale. If we can't find any question in his - * locale we return challenge questions from the default en_US locale. - * - * @param user - * @return - * @throws IdentityRecoveryServerException - */ - public ChallengeQuestion[] getChallengeQuestionsForUser(User user) - throws IdentityRecoveryException { - if (user == null) { - log.error("User object provided is null."); - throw new IdentityRecoveryClientException("User object provided is null."); - } - - String tenantDomain = CarbonContext.getThreadLocalCarbonContext().getTenantDomain(); - List challengeQuestionList; - try { - challengeQuestionList = questionManager.getAllChallengeQuestionsForUser(tenantDomain, user); - return challengeQuestionList.toArray(new ChallengeQuestion[challengeQuestionList.size()]); - } catch (IdentityRecoveryException e) { - String errorMgs = "Error loading challenge questions for user : %s@%s."; - log.error(String.format(errorMgs, user.getUserName(), tenantDomain), e); - throw new IdentityRecoveryException(String.format(errorMgs, user.getUserName(), tenantDomain), e); - } - } - - /** - * Get all tenant questions of a locale in a tenant domain - * - * @param tenantDomain - * @param locale - * @return - * @throws IdentityRecoveryServerException - */ - public ChallengeQuestion[] getChallengeQuestionsForLocale(String tenantDomain, String locale) - throws IdentityRecoveryException { - // check for cross tenant access - checkCrossTenantAccess(tenantDomain); - List challengeQuestionList; - try { - challengeQuestionList = questionManager.getAllChallengeQuestions(tenantDomain, locale); - return challengeQuestionList.toArray(new ChallengeQuestion[challengeQuestionList.size()]); - } catch (IdentityRecoveryException e) { - String errorMgs = String.format("Error loading challenge questions for tenant %s in %s locale.", - tenantDomain, locale); - log.error(errorMgs, e); - throw new IdentityRecoveryException(errorMgs, e); - } - } - - /** - * Set challenge questions for a tenant domain - * - * @param challengeQuestions - * @param tenantDomain - * @throws IdentityRecoveryException - */ - public void setChallengeQuestionsOfTenant(ChallengeQuestion[] challengeQuestions, String tenantDomain) - throws IdentityRecoveryException { - checkCrossTenantAccess(tenantDomain); - try { - questionManager.addChallengeQuestions(challengeQuestions, tenantDomain); - } catch (IdentityRecoveryException e) { - String errorMsg = "Error setting challenge questions for tenant domain %s."; - log.error(String.format(errorMsg, tenantDomain), e); - throw new IdentityRecoveryException(String.format(errorMsg, tenantDomain), e); - } - } - - /** - * Set challenge questions for a tenant domain - * - * @param challengeQuestions - * @param tenantDomain - * @throws IdentityRecoveryException - */ - public void deleteChallengeQuestionsOfTenant(ChallengeQuestion[] challengeQuestions, String tenantDomain) - throws IdentityRecoveryException { - checkCrossTenantAccess(tenantDomain); - try { - questionManager.deleteChallengeQuestions(challengeQuestions, tenantDomain); - } catch (IdentityRecoveryException e) { - String errorMsg = "Error deleting challenge questions in tenant domain %s."; - log.error(String.format(errorMsg, tenantDomain), e); - throw new IdentityRecoveryException(String.format(errorMsg, tenantDomain), e); - } - } - - /** - * Set challenge question answers for a user - * - * @param user - * @param userChallengeAnswers - * @throws IdentityRecoveryException - */ - public void setUserChallengeAnswers(User user, UserChallengeAnswer[] userChallengeAnswers) - throws IdentityRecoveryException { - if (user == null) { - log.error("User object provided is null."); - throw new IdentityRecoveryClientException("User object provided is null."); - } - - String tenantAwareUserName = MultitenantUtils.getTenantAwareUsername(user.getUserName()); - - if (ArrayUtils.isEmpty(userChallengeAnswers)) { - String errorMsg = "No challenge question answers provided by the user " + tenantAwareUserName; - log.error(errorMsg); - throw new IdentityRecoveryClientException(errorMsg); - } - - String tenantDomain = CarbonContext.getThreadLocalCarbonContext().getTenantDomain(); - String loggedInName = CarbonContext.getThreadLocalCarbonContext().getUsername(); - - // TODO externalize the authorization logic - if (tenantAwareUserName != null && !isValidUser(user.getUserStoreDomain(), tenantAwareUserName, loggedInName)) { - boolean isAuthorized = isUserAuthorized(loggedInName, tenantDomain); - if (!isAuthorized) { - throw new IdentityRecoveryClientException - ("Unauthorized access!! Possible elevation of privilege attack. " + "User " + loggedInName + - " trying to change challenge questions for user " + tenantAwareUserName); - } - } else if (tenantAwareUserName == null) { - tenantAwareUserName = loggedInName; - } - - try { - questionManager.setChallengesOfUser(user, userChallengeAnswers); - - } catch (IdentityException e) { - String errorMessage = "Error while persisting user challenges for user : " + tenantAwareUserName; - log.error(errorMessage, e); - throw new IdentityRecoveryException(errorMessage, e); - } - } - - /** - * Get Challenge question answers along with their encrypted answers of a user - * - * @param user - * @return - * @throws IdentityRecoveryException - */ - public UserChallengeAnswer[] getUserChallengeAnswers(User user) throws IdentityRecoveryException { - if (user == null) { - log.error("User object provided is null."); - throw new IdentityRecoveryClientException("User object provided is null."); - } - - String tenantAwareUserName = MultitenantUtils.getTenantAwareUsername(user.getUserName()); - String tenantDomain = CarbonContext.getThreadLocalCarbonContext().getTenantDomain(); - String loggedInName = CarbonContext.getThreadLocalCarbonContext().getUsername(); - - // TODO externalize authorization - if (tenantAwareUserName != null && !isValidUser(user.getUserStoreDomain(), tenantAwareUserName, loggedInName)) { - boolean isAuthorized = isUserAuthorized(loggedInName, tenantDomain); - if (!isAuthorized) { - throw new IdentityRecoveryClientException( - "Unauthorized access!! Possible violation of confidentiality. " + "User " + loggedInName + - " trying to get challenge questions for user " + tenantAwareUserName); - } - } else if (tenantAwareUserName == null) { - tenantAwareUserName = loggedInName; - } - - try { - return questionManager.getChallengeAnswersOfUser(user); - } catch (IdentityRecoveryException e) { - String msg = "Error retrieving user challenge answers for " + tenantAwareUserName; - log.error(msg, e); - throw new IdentityRecoveryException(msg, e); - } - } - - private boolean isUserAuthorized(String tenantAwareUserName, String tenantDomain) - throws IdentityRecoveryException { - - int tenantId = IdentityTenantUtil.getTenantId(tenantDomain); - AuthorizationManager authzManager = null; - boolean isAuthorized; - - try { - authzManager = IdentityRecoveryServiceDataHolder.getInstance().getRealmService(). - getTenantUserRealm(tenantId).getAuthorizationManager(); - - isAuthorized = authzManager.isUserAuthorized(tenantAwareUserName, "/permission/admin/manage/identity", - CarbonConstants.UI_PERMISSION_ACTION); - - } catch (UserStoreException e) { - throw new IdentityRecoveryServerException("Error occurred while checking access level for " + - "user " + tenantAwareUserName + " in tenant " + tenantDomain, e); - } - - return isAuthorized; - } - - private void checkCrossTenantAccess(String tenantDomain) throws IdentityRecoveryClientException { - String loggedInUser = CarbonContext.getThreadLocalCarbonContext().getUsername(); - String loggedInTenant = CarbonContext.getThreadLocalCarbonContext().getTenantDomain(); - - if (!StringUtils.equals(loggedInTenant, tenantDomain)) { - String errorMsg = String.format("Unauthorized Access. User %s@%s trying to retrieve challenge questions " + - "of %s tenant", loggedInUser, loggedInTenant, tenantDomain); - throw new IdentityRecoveryClientException(errorMsg); - } - - } - - /** - * Compare and verify whether the logged in user and user in the payload are same. - * - * @param userDomain user store domain of the user in the payload. - * @param tenantAwareUserName tenant aware username of the user in the payload - * @param loggedInName user name of the logged in user - * @return true/false - */ - private boolean isValidUser(String userDomain, String tenantAwareUserName, String loggedInName) { - - String loggedInUserDomain = UserCoreUtil.getDomainFromThreadLocal(); - if (StringUtils.isEmpty(loggedInUserDomain)) { - loggedInUserDomain = UserCoreConstants.PRIMARY_DEFAULT_DOMAIN_NAME; - } - if (StringUtils.isEmpty(userDomain)) { - userDomain = UserCoreConstants.PRIMARY_DEFAULT_DOMAIN_NAME; - } - String domainAppendedUsername = appendDomainToUserName(tenantAwareUserName, userDomain); - String domainAppendedLoggedInName = appendDomainToUserName(loggedInName, loggedInUserDomain); - int tenantId = CarbonContext.getThreadLocalCarbonContext().getTenantId(); - boolean isUsernameCaseSensitive = IdentityUtil.isUserStoreCaseSensitive(loggedInUserDomain, tenantId); - - if (isUsernameCaseSensitive) { - return domainAppendedUsername.equals(domainAppendedLoggedInName); - } else { - return domainAppendedUsername.equalsIgnoreCase(domainAppendedLoggedInName); - } - } - - /** - * Convert the domain name into uppercase if exists or append if not. - * - * @param username username of the user - * @param domainName user store domain of the user - * @return domain name appended username as a string - */ - private String appendDomainToUserName(String username, String domainName) { - - int domainSeparatorIndex = username.indexOf(UserCoreConstants.DOMAIN_SEPARATOR); - if (domainSeparatorIndex > 0) { - String existingDomainName = username.substring(0, domainSeparatorIndex); - return username.replace(existingDomainName, existingDomainName.toUpperCase()); - } else { - return UserCoreUtil.addDomainToName(username, domainName); - } - } -} diff --git a/components/org.wso2.carbon.identity.recovery/src/main/java/org/wso2/carbon/identity/recovery/util/Utils.java b/components/org.wso2.carbon.identity.recovery/src/main/java/org/wso2/carbon/identity/recovery/util/Utils.java index e111173406..24279506a9 100644 --- a/components/org.wso2.carbon.identity.recovery/src/main/java/org/wso2/carbon/identity/recovery/util/Utils.java +++ b/components/org.wso2.carbon.identity.recovery/src/main/java/org/wso2/carbon/identity/recovery/util/Utils.java @@ -56,7 +56,6 @@ import org.wso2.carbon.identity.recovery.exception.SelfRegistrationClientException; import org.wso2.carbon.identity.recovery.exception.SelfRegistrationException; import org.wso2.carbon.identity.recovery.internal.IdentityRecoveryServiceDataHolder; -import org.wso2.carbon.identity.recovery.model.ChallengeQuestion; import org.wso2.carbon.identity.recovery.model.UserRecoveryData; import org.wso2.carbon.identity.user.functionality.mgt.UserFunctionalityMgtConstants; import org.wso2.carbon.user.api.Claim; @@ -613,29 +612,6 @@ public static String getChallengeSetDirFromUri(String challengeSetUri) { return components.length > 1 ? components[1] : components[0]; } - public static ChallengeQuestion[] getDefaultChallengeQuestions() { - - List challengeQuestions = new ArrayList<>(); - // locale en_US, challengeSet1 - int count = 0; - for (String question : IdentityRecoveryConstants.Questions.SECRET_QUESTIONS_SET01) { - String setId = IdentityRecoveryConstants.WSO2CARBON_CLAIM_DIALECT + "/" + "challengeQuestion1"; - String questionId = "question" + (++count); - challengeQuestions.add( - new ChallengeQuestion(setId, questionId, question, IdentityRecoveryConstants.LOCALE_EN_US)); - } - - count = 0; - for (String question : IdentityRecoveryConstants.Questions.SECRET_QUESTIONS_SET02) { - String setId = IdentityRecoveryConstants.WSO2CARBON_CLAIM_DIALECT + "/" + "challengeQuestion2"; - String questionId = "question" + (++count); - challengeQuestions.add( - new ChallengeQuestion(setId, questionId, question, IdentityRecoveryConstants.LOCALE_EN_US)); - } - - return challengeQuestions.toArray(new ChallengeQuestion[challengeQuestions.size()]); - } - public static boolean isAccountLocked(User user) throws IdentityRecoveryException { try { diff --git a/components/org.wso2.carbon.identity.recovery/src/main/resources/META-INF/services.xml b/components/org.wso2.carbon.identity.recovery/src/main/resources/META-INF/services.xml index 1b5e5a0825..b72ad1de8d 100644 --- a/components/org.wso2.carbon.identity.recovery/src/main/resources/META-INF/services.xml +++ b/components/org.wso2.carbon.identity.recovery/src/main/resources/META-INF/services.xml @@ -16,39 +16,4 @@ --> - - - https - - - org.wso2.carbon.identity.recovery.services.ChallengeQuestionManagementAdminService - - - - /permission/admin/login - - - /permission/admin/login - - - /permission/admin/login - - - /permission/admin/configure/security/questions, /permission/admin/manage/identity/challenge - - - /permission/admin/manage/identity - - - /permission/admin/login - - - /permission/admin/login - - - true - true - /permission/admin/manage/identity - - diff --git a/components/org.wso2.carbon.identity.recovery/src/test/java/org/wso2/carbon/identity/recovery/handler/request/PostAuthnMissingChallengeQuestionsHandlerTest.java b/components/org.wso2.carbon.identity.recovery/src/test/java/org/wso2/carbon/identity/recovery/handler/request/PostAuthnMissingChallengeQuestionsHandlerTest.java deleted file mode 100644 index f0c67f3e67..0000000000 --- a/components/org.wso2.carbon.identity.recovery/src/test/java/org/wso2/carbon/identity/recovery/handler/request/PostAuthnMissingChallengeQuestionsHandlerTest.java +++ /dev/null @@ -1,358 +0,0 @@ -/* - * Copyright (c) 2018, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. - * - * WSO2 Inc. 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.recovery.handler.request; - -import org.mockito.Mock; -import org.mockito.MockedStatic; -import org.mockito.Mockito; -import org.mockito.MockitoAnnotations; -import org.testng.annotations.AfterMethod; -import org.testng.annotations.BeforeMethod; -import org.testng.annotations.DataProvider; -import org.testng.annotations.Test; -import org.wso2.carbon.identity.application.authentication.framework.config.ConfigurationFacade; -import org.wso2.carbon.identity.application.authentication.framework.config.model.SequenceConfig; -import org.wso2.carbon.identity.application.authentication.framework.context.AuthenticationContext; -import org.wso2.carbon.identity.application.authentication.framework.handler.request.PostAuthnHandlerFlowStatus; -import org.wso2.carbon.identity.application.authentication.framework.model.AuthenticatedUser; -import org.wso2.carbon.identity.application.common.model.IdentityProvider; -import org.wso2.carbon.identity.application.common.model.IdentityProviderProperty; -import org.wso2.carbon.identity.mgt.util.Utils; -import org.wso2.carbon.identity.recovery.ChallengeQuestionManager; -import org.wso2.carbon.identity.recovery.IdentityRecoveryConstants; -import org.wso2.carbon.identity.recovery.internal.IdentityRecoveryServiceDataHolder; -import org.wso2.carbon.identity.recovery.model.ChallengeQuestion; -import org.wso2.carbon.idp.mgt.IdentityProviderManager; -import org.wso2.carbon.user.core.UserCoreConstants; -import org.wso2.carbon.user.core.UserRealm; -import org.wso2.carbon.user.core.UserStoreManager; -import org.wso2.carbon.user.core.service.RealmService; -import org.wso2.carbon.utils.multitenancy.MultitenantUtils; - -import java.util.ArrayList; -import java.util.Enumeration; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Vector; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import static org.mockito.Mockito.spy; -import static org.testng.Assert.assertEquals; -import static org.testng.Assert.assertNotNull; -import static org.mockito.Mockito.when; -import static org.mockito.Mockito.doNothing; -import static org.mockito.Mockito.mock; -import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.ArgumentMatchers.any; - -/** - * This class will test the Post Authentication Handler for Missing Challenge Questions - **/ -public class PostAuthnMissingChallengeQuestionsHandlerTest { - private static final String CHALLENGE_QUESTIONS_REQUESTED = "challengeQuestionsRequested"; - @Mock - private HttpServletRequest httpServletRequest; - @Mock - private HttpServletResponse httpServletResponse; - @Mock - private IdentityProviderManager identityProviderManager; - @Mock - private IdentityRecoveryServiceDataHolder frameworkServiceDataHolder; - @Mock - private ChallengeQuestionManager challengeQuestionManager; - @Mock - private ConfigurationFacade configurationFacade; - - private MockedStatic mockedHttpServletResponse; - private MockedStatic mockedIdentityProviderManager; - private MockedStatic mockedMultitenantUtils; - private MockedStatic mockedUtils; - private MockedStatic mockedIdentityRecoveryServiceDataHolder; - private MockedStatic mockedChallengeQuestionManager; - private MockedStatic mockedConfigurationFacade; - - @BeforeMethod - public void setup() { - - // initialize all the @Mock objects - MockitoAnnotations.openMocks(this); - mockedHttpServletResponse = Mockito.mockStatic(HttpServletResponse.class); - mockedIdentityProviderManager = Mockito.mockStatic(IdentityProviderManager.class); - mockedMultitenantUtils = Mockito.mockStatic(MultitenantUtils.class); - mockedUtils = Mockito.mockStatic(Utils.class); - mockedIdentityRecoveryServiceDataHolder = Mockito.mockStatic(IdentityRecoveryServiceDataHolder.class); - mockedChallengeQuestionManager = Mockito.mockStatic(ChallengeQuestionManager.class); - mockedConfigurationFacade = Mockito.mockStatic(ConfigurationFacade.class); - } - - @AfterMethod - public void tearDown() { - mockedHttpServletResponse.close(); - mockedIdentityProviderManager.close(); - mockedMultitenantUtils.close(); - mockedUtils.close(); - mockedIdentityRecoveryServiceDataHolder.close(); - mockedChallengeQuestionManager.close(); - mockedConfigurationFacade.close(); - } - - @Test(description = "Test get instance method") - public void testGetInstance() { - - testSingleton( - PostAuthnMissingChallengeQuestionsHandler.getInstance(), - PostAuthnMissingChallengeQuestionsHandler.getInstance() - ); - } - - @DataProvider(name = "forceChallengeQuestionSettings") - public Object[][] forceChallengeQuestionSettings() { - - return new Object[][]{ - {"false"}, - {"random_text"}, - {null}, - }; - } - - @Test(dataProvider = "forceChallengeQuestionSettings", description = "Test the functionality of the setting to " + - "force challenge questions") - public void testSettingTheOptionToForceChallengeQuestions(String setting) throws Exception { - - AuthenticationContext context = spy(new AuthenticationContext()); - when(context.getTenantDomain()).thenReturn("carbon.super"); - IdentityProvider residentIdp = spy(new IdentityProvider()); - IdentityProviderProperty[] idpProperties = new IdentityProviderProperty[1]; - IdentityProviderProperty idpProp = new IdentityProviderProperty(); - if (setting != null) { - idpProp.setName(IdentityRecoveryConstants.ConnectorConfig.FORCE_ADD_PW_RECOVERY_QUESTION); - idpProp.setValue(setting); - } else { - idpProp.setName(IdentityRecoveryConstants.ConnectorConfig.ACCOUNT_LOCK_ON_CREATION); - idpProp.setValue("true"); - } - idpProperties[0] = idpProp; - residentIdp.setIdpProperties(idpProperties); - mockedIdentityProviderManager.when(IdentityProviderManager::getInstance).thenReturn(identityProviderManager); - when(identityProviderManager.getResidentIdP("carbon.super")).thenReturn(residentIdp); - PostAuthnHandlerFlowStatus flowStatus = PostAuthnMissingChallengeQuestionsHandler.getInstance().handle - (httpServletRequest, httpServletResponse, context); - String expectedResult; - if (setting == null) { - setting = "null"; - } - switch (setting) { - case "false": - expectedResult = PostAuthnHandlerFlowStatus.SUCCESS_COMPLETED.name(); - break; - case "true": - expectedResult = PostAuthnHandlerFlowStatus.SUCCESS_COMPLETED.name(); - break; - case "null": - expectedResult = PostAuthnHandlerFlowStatus.UNSUCCESS_COMPLETED.name(); - break; - default: - expectedResult = PostAuthnHandlerFlowStatus.SUCCESS_COMPLETED.name(); - break; - } - assertEquals(flowStatus.name(), expectedResult); - } - - @Test(description = "Test the behaviour of the handler if the user is null") - public void testForNullUser() throws Exception { - - AuthenticationContext context = spy(new AuthenticationContext()); - when(context.getTenantDomain()).thenReturn("carbon.super"); - IdentityProvider residentIdp = spy(new IdentityProvider()); - IdentityProviderProperty[] idpProperties = new IdentityProviderProperty[1]; - IdentityProviderProperty idpProp = new IdentityProviderProperty(); - idpProp.setName(IdentityRecoveryConstants.ConnectorConfig.FORCE_ADD_PW_RECOVERY_QUESTION); - idpProp.setValue("true"); - idpProperties[0] = idpProp; - residentIdp.setIdpProperties(idpProperties); - mockedIdentityProviderManager.when(IdentityProviderManager::getInstance).thenReturn(identityProviderManager); - when(identityProviderManager.getResidentIdP("carbon.super")).thenReturn(residentIdp); - SequenceConfig sequenceConfig = spy(new SequenceConfig()); - when(sequenceConfig.getAuthenticatedUser()).thenReturn(null); - context.setSequenceConfig(sequenceConfig); - PostAuthnHandlerFlowStatus flowStatus = PostAuthnMissingChallengeQuestionsHandler.getInstance().handle - (httpServletRequest, httpServletResponse, context); - String expectedResult = PostAuthnHandlerFlowStatus.UNSUCCESS_COMPLETED.name(); - assertEquals(flowStatus.name(), expectedResult); - } - - @Test(description = "Test the flow for the user who has already given the challenge questions") - public void testAlreadyChallengeQuestionProvidedUserFlow() throws Exception { - - AuthenticationContext context = spy(new AuthenticationContext()); - when(context.getTenantDomain()).thenReturn("carbon.super"); - IdentityProvider residentIdp = spy(new IdentityProvider()); - IdentityProviderProperty[] idpProperties = new IdentityProviderProperty[1]; - IdentityProviderProperty idpProp = new IdentityProviderProperty(); - idpProp.setName(IdentityRecoveryConstants.ConnectorConfig.FORCE_ADD_PW_RECOVERY_QUESTION); - idpProp.setValue("true"); - idpProperties[0] = idpProp; - residentIdp.setIdpProperties(idpProperties); - mockedIdentityProviderManager.when(IdentityProviderManager::getInstance).thenReturn(identityProviderManager); - when(identityProviderManager.getResidentIdP("carbon.super")).thenReturn(residentIdp); - SequenceConfig sequenceConfig = spy(new SequenceConfig()); - AuthenticatedUser user = spy(new AuthenticatedUser()); - user.setUserName("admin"); - when(sequenceConfig.getAuthenticatedUser()).thenReturn(user); - context.setSequenceConfig(sequenceConfig); - mockedMultitenantUtils.when(() -> MultitenantUtils.getTenantDomain("admin")).thenReturn("carbon.super"); - mockedUtils.when(() -> Utils.getTenantId("carbon.super")).thenReturn(-1234); - mockedIdentityRecoveryServiceDataHolder.when(IdentityRecoveryServiceDataHolder::getInstance) - .thenReturn(frameworkServiceDataHolder); - RealmService realmService = mock(RealmService.class); - UserStoreManager userStoreManager = mock(UserStoreManager.class); - UserRealm userRealm = mock(UserRealm.class); - when(userRealm.getUserStoreManager()).thenReturn(userStoreManager); - when(realmService.getTenantUserRealm(-1234)).thenReturn(userRealm); - when(frameworkServiceDataHolder.getRealmService()).thenReturn(realmService); - when(userRealm.getUserStoreManager()).thenReturn(userStoreManager); - Map claimsMap = new HashMap<>(); - claimsMap.put(IdentityRecoveryConstants.CHALLENGE_QUESTION_URI, "dummy_data"); - when(userStoreManager.getUserClaimValues("admin", new String[]{IdentityRecoveryConstants - .CHALLENGE_QUESTION_URI}, UserCoreConstants.DEFAULT_PROFILE)).thenReturn(claimsMap); - PostAuthnHandlerFlowStatus flowStatus = PostAuthnMissingChallengeQuestionsHandler.getInstance().handle - (httpServletRequest, httpServletResponse, context); - String expectedResult = PostAuthnHandlerFlowStatus.SUCCESS_COMPLETED.name(); - assertEquals(flowStatus.name(), expectedResult); - } - - @Test(description = "Test the flow of challenge question post authentication handler before requesting challenge " + - "questions from the user") - public void testBeforeRequestingChallengeQuestionFlow() throws Exception { - - AuthenticationContext context = spy(new AuthenticationContext()); - when(context.getTenantDomain()).thenReturn("carbon.super"); - IdentityProvider residentIdp = spy(new IdentityProvider()); - IdentityProviderProperty[] idpProperties = new IdentityProviderProperty[1]; - IdentityProviderProperty idpProp = new IdentityProviderProperty(); - idpProp.setName(IdentityRecoveryConstants.ConnectorConfig.FORCE_ADD_PW_RECOVERY_QUESTION); - idpProp.setValue("true"); - idpProperties[0] = idpProp; - residentIdp.setIdpProperties(idpProperties); - mockedIdentityProviderManager.when(IdentityProviderManager::getInstance).thenReturn(identityProviderManager); - when(identityProviderManager.getResidentIdP("carbon.super")).thenReturn(residentIdp); - SequenceConfig sequenceConfig = spy(new SequenceConfig()); - AuthenticatedUser user = spy(new AuthenticatedUser()); - user.setUserName("admin"); - when(sequenceConfig.getAuthenticatedUser()).thenReturn(user); - context.setSequenceConfig(sequenceConfig); - mockedMultitenantUtils.when(() -> MultitenantUtils.getTenantDomain("admin")).thenReturn("carbon.super"); - mockedUtils.when(() -> Utils.getTenantId("carbon.super")).thenReturn(-1234); - mockedIdentityRecoveryServiceDataHolder.when(IdentityRecoveryServiceDataHolder::getInstance) - .thenReturn(frameworkServiceDataHolder); - RealmService realmService = mock(RealmService.class); - UserStoreManager userStoreManager = mock(UserStoreManager.class); - UserRealm userRealm = mock(UserRealm.class); - when(userRealm.getUserStoreManager()).thenReturn(userStoreManager); - when(realmService.getTenantUserRealm(-1234)).thenReturn(userRealm); - when(frameworkServiceDataHolder.getRealmService()).thenReturn(realmService); - when(userRealm.getUserStoreManager()).thenReturn(userStoreManager); - Map claimsMap = new HashMap<>(); - when(userStoreManager.getUserClaimValues("admin", new String[]{IdentityRecoveryConstants - .CHALLENGE_QUESTION_URI}, UserCoreConstants.DEFAULT_PROFILE)).thenReturn(claimsMap); - List challengeQuestions = new ArrayList<>(); - ChallengeQuestion challengeQuestion = spy(new ChallengeQuestion()); - challengeQuestion.setQuestionSetId("dummy_set"); - challengeQuestion.setQuestionId("dummy_id"); - challengeQuestion.setQuestion("dummy_question"); - challengeQuestions.add(challengeQuestion); - when(challengeQuestionManager.getAllChallengeQuestions("carbon.super")).thenReturn(challengeQuestions); - mockedChallengeQuestionManager.when(ChallengeQuestionManager::getInstance).thenReturn(challengeQuestionManager); - doNothing().doThrow(Exception.class).when(httpServletResponse).sendRedirect((String) any()); - when(configurationFacade.getAuthenticationEndpointURL()).thenReturn(""); - when(ConfigurationFacade.getInstance()).thenReturn(configurationFacade); - PostAuthnHandlerFlowStatus flowStatus = PostAuthnMissingChallengeQuestionsHandler.getInstance().handle - (httpServletRequest, httpServletResponse, context); - String expectedResult = PostAuthnHandlerFlowStatus.INCOMPLETE.name(); - assertEquals(flowStatus.name(), expectedResult); - } - - @Test(description = "Test the flow of challenge question post authentication handler after requesting challenge " + - "questions from the user") - public void testAfterRequestingChallengeQuestionFlow() throws Exception { - - AuthenticationContext context = spy(new AuthenticationContext()); - when(context.getTenantDomain()).thenReturn("carbon.super"); - IdentityProvider residentIdp = spy(new IdentityProvider()); - IdentityProviderProperty[] idpProperties = new IdentityProviderProperty[1]; - IdentityProviderProperty idpProp = new IdentityProviderProperty(); - idpProp.setName(IdentityRecoveryConstants.ConnectorConfig.FORCE_ADD_PW_RECOVERY_QUESTION); - idpProp.setValue("true"); - idpProperties[0] = idpProp; - residentIdp.setIdpProperties(idpProperties); - mockedIdentityProviderManager.when(IdentityProviderManager::getInstance).thenReturn(identityProviderManager); - when(identityProviderManager.getResidentIdP("carbon.super")).thenReturn(residentIdp); - SequenceConfig sequenceConfig = spy(new SequenceConfig()); - AuthenticatedUser user = spy(new AuthenticatedUser()); - user.setUserName("admin"); - when(sequenceConfig.getAuthenticatedUser()).thenReturn(user); - context.setSequenceConfig(sequenceConfig); - mockedMultitenantUtils.when(() -> MultitenantUtils.getTenantDomain("admin")).thenReturn("carbon.super"); - mockedUtils.when(() -> Utils.getTenantId("carbon.super")).thenReturn(-1234); - mockedIdentityRecoveryServiceDataHolder.when(IdentityRecoveryServiceDataHolder::getInstance) - .thenReturn(frameworkServiceDataHolder); - RealmService realmService = mock(RealmService.class); - UserStoreManager userStoreManager = mock(UserStoreManager.class); - UserRealm userRealm = mock(UserRealm.class); - when(userRealm.getUserStoreManager()).thenReturn(userStoreManager); - when(realmService.getTenantUserRealm(-1234)).thenReturn(userRealm); - when(frameworkServiceDataHolder.getRealmService()).thenReturn(realmService); - when(userRealm.getUserStoreManager()).thenReturn(userStoreManager); - Map claimsMap = new HashMap<>(); - when(userStoreManager.getUserClaimValues("admin", new String[]{IdentityRecoveryConstants - .CHALLENGE_QUESTION_URI}, UserCoreConstants.DEFAULT_PROFILE)).thenReturn(claimsMap); - List challengeQuestions = new ArrayList<>(); - ChallengeQuestion challengeQuestion = spy(new ChallengeQuestion()); - challengeQuestion.setQuestionSetId("dummy_set"); - challengeQuestion.setQuestionId("dummy_id"); - challengeQuestion.setQuestion("dummy_question"); - challengeQuestions.add(challengeQuestion); - when(challengeQuestionManager.getAllChallengeQuestions("carbon.super")).thenReturn(challengeQuestions); - mockedChallengeQuestionManager.when(ChallengeQuestionManager::getInstance).thenReturn(challengeQuestionManager); - doNothing().doThrow(Exception.class).when(httpServletResponse).sendRedirect((String) any()); - when(configurationFacade.getAuthenticationEndpointURL()).thenReturn(""); - mockedConfigurationFacade.when(ConfigurationFacade::getInstance).thenReturn(configurationFacade); - when(context.getParameter(CHALLENGE_QUESTIONS_REQUESTED)).thenReturn(true); - Vector set = new Vector<>(); - set.add("Q-dummy_question"); - set.add("A-dummy_answer"); - Enumeration paramNames = new Vector(set).elements(); - when(httpServletRequest.getParameterNames()).thenReturn(paramNames); - when(httpServletRequest.getParameter(anyString())).thenReturn("dummy_question"); - PostAuthnHandlerFlowStatus flowStatus = PostAuthnMissingChallengeQuestionsHandler.getInstance().handle - (httpServletRequest, httpServletResponse, context); - String expectedResult = PostAuthnHandlerFlowStatus.SUCCESS_COMPLETED.name(); - assertEquals(flowStatus.name(), expectedResult); - } - - public static void testSingleton(Object instance, Object anotherInstance) { - - assertNotNull(instance); - assertNotNull(anotherInstance); - assertEquals(instance, anotherInstance); - } - -} diff --git a/features/org.wso2.carbon.identity.governance.feature/pom.xml b/features/org.wso2.carbon.identity.governance.feature/pom.xml index b70eb70a8a..fec1f311ae 100644 --- a/features/org.wso2.carbon.identity.governance.feature/pom.xml +++ b/features/org.wso2.carbon.identity.governance.feature/pom.xml @@ -51,12 +51,6 @@ ${project.version} zip - - org.wso2.carbon.identity.governance - org.wso2.carbon.identity.recovery.ui.feature - ${project.version} - zip - org.wso2.carbon.identity.governance org.wso2.carbon.identity.captcha.server.feature @@ -154,9 +148,6 @@ org.wso2.carbon.identity.governance:org.wso2.carbon.identity.idle.account.identification.server.feature - - org.wso2.carbon.identity.governance:org.wso2.carbon.identity.recovery.ui.feature - org.wso2.carbon.identity.governance:org.wso2.carbon.identity.piicontroller.server.feature diff --git a/features/org.wso2.carbon.identity.recovery.ui.feature/pom.xml b/features/org.wso2.carbon.identity.recovery.ui.feature/pom.xml deleted file mode 100644 index 8477335cdb..0000000000 --- a/features/org.wso2.carbon.identity.recovery.ui.feature/pom.xml +++ /dev/null @@ -1,83 +0,0 @@ - - - - - - - org.wso2.carbon.identity.governance - identity-governance - 1.8.85-SNAPSHOT - ../../pom.xml - - - 4.0.0 - org.wso2.carbon.identity.recovery.ui.feature - pom - WSO2 Carbon - Identity Recovery UI Feature - http://wso2.org - This feature contains the bundles required for Front-end Identity Recovery functionality - - - - - org.wso2.carbon.identity.governance - org.wso2.carbon.identity.recovery.ui - ${project.version} - - - org.wso2.carbon.identity.governance - org.wso2.carbon.identity.recovery.stub - ${project.version} - - - - - - - org.wso2.maven - carbon-p2-plugin - ${carbon.p2.plugin.version} - - - p2-feature-generation - package - - p2-feature-gen - - - org.wso2.carbon.identity.recovery.ui - ../../etc/feature.properties - - - org.wso2.carbon.p2.category.type:console - org.eclipse.equinox.p2.type.group:false - - - - org.wso2.carbon.identity.governance:org.wso2.carbon.identity.recovery.ui - org.wso2.carbon.identity.governance:org.wso2.carbon.identity.recovery.stub - - - - - - - - - - - diff --git a/pom.xml b/pom.xml index 6ec190538a..ac9ffee1c0 100644 --- a/pom.xml +++ b/pom.xml @@ -45,7 +45,6 @@ components/org.wso2.carbon.identity.governance components/org.wso2.carbon.identity.recovery - components/org.wso2.carbon.identity.recovery.ui components/org.wso2.carbon.identity.recovery.endpoint components/org.wso2.carbon.identity.api.user.recovery components/org.wso2.carbon.identity.captcha @@ -63,11 +62,8 @@ components/org.wso2.carbon.identity.password.expiry components/org.wso2.carbon.identity.idle.account.identification - service-stubs/identity - features/org.wso2.carbon.identity.recovery.server.feature features/org.wso2.carbon.identity.user.server.feature - features/org.wso2.carbon.identity.recovery.ui.feature features/org.wso2.carbon.identity.governance.server.feature features/org.wso2.carbon.identity.captcha.server.feature features/org.wso2.carbon.identity.password.history.server.feature diff --git a/service-stubs/identity/org.wso2.carbon.identity.recovery.stub/pom.xml b/service-stubs/identity/org.wso2.carbon.identity.recovery.stub/pom.xml deleted file mode 100644 index 191307aa4c..0000000000 --- a/service-stubs/identity/org.wso2.carbon.identity.recovery.stub/pom.xml +++ /dev/null @@ -1,117 +0,0 @@ - - - - - - org.wso2.carbon.identity.governance - carbon-service-stubs - 1.8.85-SNAPSHOT - ../pom.xml - - - 4.0.0 - org.wso2.carbon.identity.recovery.stub - bundle - WSO2 Carbon - Identity Recovery Stub - http://wso2.org - - - - org.apache.axis2.wso2 - axis2 - - - org.apache.axis2.wso2 - axis2-client - - - org.apache.ws.commons.axiom.wso2 - axiom - - - - - - - org.apache.maven.plugins - maven-antrun-plugin - 1.1 - - - source-code-generation - process-resources - - run - - - - - - - - - - - - - - - - - - - - org.codehaus.mojo - build-helper-maven-plugin - - - add-source - generate-sources - - add-source - - - - - target/generated-code/src - - - - - - - - org.apache.felix - maven-bundle-plugin - true - - - ${project.artifactId} - ${project.artifactId} - - org.wso2.carbon.identity.recovery.stub.*;version="${identity.governance.exp.pkg.version}", - org.wso2.carbon.identity.recovery.xsd;version="${identity.governance.exp.pkg.version}", - org.wso2.carbon.identity.application.common.model.xsd;version="${identity.governance.exp.pkg.version}" - - - - - - - - - \ No newline at end of file diff --git a/service-stubs/identity/org.wso2.carbon.identity.recovery.stub/src/main/resources/ChallengeQuestionManagementAdminService.wsdl b/service-stubs/identity/org.wso2.carbon.identity.recovery.stub/src/main/resources/ChallengeQuestionManagementAdminService.wsdl deleted file mode 100644 index d9dfd5b7d4..0000000000 --- a/service-stubs/identity/org.wso2.carbon.identity.recovery.stub/src/main/resources/ChallengeQuestionManagementAdminService.wsdl +++ /dev/null @@ -1,469 +0,0 @@ - - ChallengeQuestionManagementAdminService - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/service-stubs/identity/pom.xml b/service-stubs/identity/pom.xml deleted file mode 100644 index 51271af831..0000000000 --- a/service-stubs/identity/pom.xml +++ /dev/null @@ -1,53 +0,0 @@ - - - - - - org.wso2.carbon.identity.governance - identity-governance - 1.8.85-SNAPSHOT - ../../pom.xml - - - 4.0.0 - carbon-service-stubs - pom - WSO2 Carbon - Service Stubs - Aggregator Module - http://wso2.org - - - org.wso2.carbon.identity.recovery.stub - - - - - - org.codehaus.mojo - build-helper-maven-plugin - 1.7 - - - com.github.spotbugs - spotbugs-maven-plugin - - true - - - - - -