<%--
~ Copyright (c) 2021, WSO2 Inc. (http://www.wso2.com). All Rights Reserved.
~
~ This software is the property of WSO2 Inc. and its suppliers, if any.
~ Dissemination of any information or reproduction of any material contained
~ herein in any form is strictly forbidden, unless permitted by WSO2 expressly.
~ You may not alter or remove any copyright or other notice from copies of this content."
--%>

<%@ page contentType="text/html;charset=UTF-8" language="java" %>

<%@ page import="org.apache.commons.collections.map.HashedMap" %>
<%@ page import="org.apache.commons.lang.StringUtils" %>
<%@ page import="org.wso2.carbon.identity.mgt.endpoint.util.IdentityManagementEndpointConstants" %>
<%@ page import="org.wso2.carbon.identity.mgt.endpoint.util.IdentityManagementEndpointUtil" %>
<%@ page import="org.wso2.carbon.identity.mgt.endpoint.util.client.ApiException" %>
<%@ page import="org.wso2.carbon.identity.mgt.endpoint.util.client.api.UsernameRecoveryApi" %>
<%@ page import="org.wso2.carbon.identity.mgt.endpoint.util.client.api.PasswordRecoveryApiV1" %>
<%@ page import="org.wso2.carbon.identity.mgt.endpoint.util.client.model.Claim" %>
<%@ page import="org.wso2.carbon.identity.mgt.endpoint.util.client.model.UserClaim" %>
<%@ page import="org.wso2.carbon.user.core.util.UserCoreUtil" %>
<%@ page import="org.wso2.carbon.utils.multitenancy.MultitenantUtils" %>
<%@ page import="java.util.ArrayList" %>
<%@ page import="java.util.List" %>
<%@ page import="java.util.Map" %>
<%@ page import="org.wso2.carbon.identity.mgt.endpoint.util.client.model.Property" %>
<%@ page import="java.net.URLEncoder" %>
<%@ page import="org.wso2.carbon.identity.mgt.endpoint.util.client.model.passwordrecovery.v1.*" %>
<%@ page import="org.wso2.carbon.utils.CarbonUtils" %>

<jsp:directive.include file="includes/localize.jsp"/>
<jsp:directive.include file="tenant-resolve.jsp"/>

<%
    boolean isPasswordRecoveryEmailConfirmation =
            Boolean.parseBoolean(request.getParameter("isPasswordRecoveryEmailConfirmation"));
    boolean isUsernameRecovery = Boolean.parseBoolean(request.getParameter("isUsernameRecovery"));
    boolean isPasswordRecoveryWithClaimsNotify =
            Boolean.parseBoolean(request.getParameter("isPasswordRecoveryWithClaimsNotify"));

    // Common parameters for password recovery with email and self registration with email
    String username = request.getParameter("username");
    String sessionDataKey = request.getParameter("sessionDataKey");
    String confirmationKey = request.getParameter("confirmationKey");
    String callback = request.getParameter("callback");
    String userTenantHint = request.getParameter("t");

    if (StringUtils.isBlank(callback)) {
        callback = IdentityManagementEndpointUtil.getUserPortalUrl(
                application.getInitParameter(IdentityManagementEndpointConstants.ConfigConstants.USER_PORTAL_URL), tenantDomain);
    }

    //Modifed-for-Asgardeo.
    // When email as username is used without enabling isEmailUsername, we expect username to be fully qualified.
    if (StringUtils.isNotBlank(userTenantHint)) {
        username = UserCoreUtil.addTenantDomainToEntry(username, userTenantHint);
    } else {
        username = UserCoreUtil.addTenantDomainToEntry(username, userTenant);
    }

    // Password recovery parameters
    String recoveryOption = request.getParameter("recoveryOption");

    if (isUsernameRecovery) {
        // Username Recovery Scenario
        List<Claim> claims;
        UsernameRecoveryApi usernameRecoveryApi = new UsernameRecoveryApi();
        try {
            claims = usernameRecoveryApi.getClaimsForUsernameRecovery(tenantDomain, true);
        } catch (ApiException e) {
            IdentityManagementEndpointUtil.addErrorInformation(request, e);
            if (!StringUtils.isBlank(username)) {
                request.setAttribute("username", username);
            }
            request.getRequestDispatcher("error.jsp").forward(request, response);
            return;
        }

        List<UserClaim> claimDTOList = new ArrayList<UserClaim>();

        for (Claim claimDTO : claims) {
            if (StringUtils.isNotBlank(request.getParameter(claimDTO.getUri()))) {
                UserClaim userClaim = new UserClaim();
                userClaim.setUri(claimDTO.getUri());
                userClaim.setValue(request.getParameter(claimDTO.getUri()).trim());
                claimDTOList.add(userClaim);
            }
        }

        try {
            Map<String, String> requestHeaders = new HashedMap();
            if (request.getParameter("g-recaptcha-response") != null) {
                requestHeaders.put("g-recaptcha-response", request.getParameter("g-recaptcha-response"));
            }
    
            usernameRecoveryApi.recoverUsernamePost(claimDTOList, tenantDomain, null, requestHeaders);
            request.setAttribute("callback", callback);
            request.setAttribute("tenantDomain", tenantDomain);
            request.getRequestDispatcher("username-recovery-complete.jsp").forward(request, response);
        } catch (ApiException e) {
            if (e.getCode() == 204) {
                request.setAttribute("error", true);
                request.setAttribute("errorMsg", IdentityManagementEndpointUtil.i18n(recoveryResourceBundle,
                        "No.valid.user.found"));
                request.getRequestDispatcher("recoveraccountrouter.do").forward(request, response);
                return;
            }

            IdentityManagementEndpointUtil.addErrorInformation(request, e);
            request.getRequestDispatcher("recoveraccountrouter.do").forward(request, response);
            return;
        }

    } else if (isPasswordRecoveryWithClaimsNotify) {
        // Let user recover password by email or security questions.
        String recoveryCode = request.getParameter("recoveryCode");
        String notificationChannel = "";

        PasswordRecoveryApiV1 passwordRecoveryApiV1 = new PasswordRecoveryApiV1();
        if (recoveryOption.equals("SECURITY_QUESTIONS")) {
            username = IdentityManagementEndpointUtil.getFullQualifiedUsername(username, tenantDomain, null);
            request.setAttribute("callback", callback);
            request.setAttribute("sessionDataKey", sessionDataKey);
            request.setAttribute("username", username);
            session.setAttribute("username", username);
            IdentityManagementEndpointUtil.addReCaptchaHeaders(request, passwordRecoveryApiV1.
                    getApiClient().getResponseHeaders());
            request.getRequestDispatcher("challenge-question-request.jsp?username=" + username).forward(request,
                    response);
            return;
        } else {
            List<Property> properties = new ArrayList<>();
            Property callbackProperty = new Property();
            callbackProperty.setKey("callback");
            callbackProperty.setValue(URLEncoder.encode(callback, "UTF-8"));
            properties.add(callbackProperty);

            Property sessionDataKeyProperty = new Property();
            sessionDataKeyProperty.setKey("sessionDataKey");
            sessionDataKeyProperty.setValue(sessionDataKey);
            properties.add(sessionDataKeyProperty);

            RecoveryRequest recoveryRequest = new RecoveryRequest();
            recoveryRequest.setProperties(properties);
            recoveryRequest.setChannelId(recoveryOption);
            recoveryRequest.setRecoveryCode(recoveryCode);
            try {
                Map<String, String> requestHeaders = new HashedMap();
                RecoveryResponse recoveryResponse = passwordRecoveryApiV1.recoverPassword(recoveryRequest,
                        tenantDomain, requestHeaders);
                notificationChannel = recoveryResponse.getNotificationChannel();
                request.setAttribute("callback", callback);
                if (notificationChannel.equals("EMAIL")) {
                    request.getRequestDispatcher("password-recovery-with-claims-notify.jsp").forward(request,
                            response);
                    return;
                } else {
                    request.setAttribute("error", true);
                    request.setAttribute("errorMsg", IdentityManagementEndpointUtil.i18n(recoveryResourceBundle,
                            "Unknown.password.recovery.option"));
                    if (!StringUtils.isBlank(username)) {
                        request.setAttribute("username", username);
                    }
                    request.getRequestDispatcher("error.jsp").forward(request, response);
                }
            }
            catch (ApiException e) {
                IdentityManagementEndpointUtil.addErrorInformation(request, e);
                if (!StringUtils.isBlank(username)) {
                    request.setAttribute("username", username);
                }
                request.getRequestDispatcher("error.jsp").forward(request, response);
                return;
            }
        }
    } else {
        request.setAttribute("sessionDataKey", sessionDataKey);
        
        if (isPasswordRecoveryEmailConfirmation) {
            session.setAttribute("username", username);
            session.setAttribute("confirmationKey", confirmationKey);
            request.setAttribute("callback", callback);
            request.getRequestDispatcher("password-reset.jsp").forward(request, response);
        } else {
            request.setAttribute("username", username);
            session.setAttribute("username", username);

            if (IdentityManagementEndpointConstants.PasswordRecoveryOptions.EMAIL.equals(recoveryOption)) {
                request.setAttribute("callback", callback);
                request.getRequestDispatcher("password-recovery-notify.jsp").forward(request, response);
            } else if (IdentityManagementEndpointConstants.PasswordRecoveryOptions.SECURITY_QUESTIONS
                    .equals(recoveryOption)) {
                request.setAttribute("callback", callback);
                request.getRequestDispatcher("challenge-question-request.jsp?username=" + username).forward(request,
                        response);
            } else {
                request.setAttribute("error", true);
                request.setAttribute("errorMsg", IdentityManagementEndpointUtil.i18n(recoveryResourceBundle,
                        "Unknown.password.recovery.option"));
                if (!StringUtils.isBlank(username)) {
                    request.setAttribute("username", username);
                }
                request.getRequestDispatcher("error.jsp").forward(request, response);
            }
        }
    }
%>
<html>
<head>
    <title></title>
</head>
<body>

</body>
</html>
