@Audit(action = AuditableActions.REQUEST_CHANGE_PASSWORD,
        principalResolverName = AuditPrincipalResolvers.REQUEST_CHANGE_PASSWORD_PRINCIPAL_RESOLVER,
        actionResolverName = AuditActionResolvers.REQUEST_CHANGE_PASSWORD_ACTION_RESOLVER,
        resourceResolverName = AuditResourceResolvers.REQUEST_CHANGE_PASSWORD_RESOURCE_RESOLVER)
    @Override
    protected Event doExecuteInternal(final RequestContext requestContext) throws Throwable {
        communicationsManager.validate();
        if (!communicationsManager.isMailSenderDefined() && !communicationsManager.isSmsSenderDefined()) {
            return getErrorEvent("contact.failed", "Unable to send email as no mail sender is defined", requestContext);
        }

        val query = buildPasswordManagementQuery(requestContext);
        if (StringUtils.isBlank(query.getUsername())) {
            return getErrorEvent("username.required", "No username is provided", requestContext);
        }

        val email = passwordManagementService.findEmail(query);
        val phone = passwordManagementService.findPhone(query);
        if (StringUtils.isBlank(email) && StringUtils.isBlank(phone)) {
            LOGGER.warn("No recipient is provided with a valid email/phone");
            return getInvalidContactEvent(requestContext);
        }
        WebUtils.putPasswordManagementQuery(requestContext, query);
        if (doesPasswordResetRequireMultifactorAuthentication(requestContext)
            && !hasPrincipalRegisteredMultifactorAuthenticationDevice(requestContext)) {
            LOGGER.warn("No registered devices for multifactor authentication could be found for [{}]", query.getUsername());
            WebUtils.addErrorMessageToContext(requestContext, "screen.mfaDenied.message");
            return eventFactory.event(this, CasWebflowConstants.TRANSITION_ID_DENY);
        }
        val service = WebUtils.getService(requestContext);
        val url = buildPasswordResetUrl(query.getUsername(), service);
        if (url != null) {
            val sendEmail = sendPasswordResetEmailToAccount(query.getUsername(), email, url, requestContext);
            val sendSms = sendPasswordResetSmsToAccount(phone, url);
            if (sendEmail.isSuccess() || sendSms) {
                return success(url);
            }
        } else {
            LOGGER.error("No password reset URL could be built and sent to [{}]", email);
        }
        LOGGER.error("Failed to notify account [{}]", email);
        return getErrorEvent("contact.failed", "Failed to send the password reset link via email address or phone", requestContext);
    }
Build the reset URL for the user.
support/cas-server-support-pm-webflow/src/main/java/org/apereo/cas/pm/web/flow/actions/SendPasswordResetInstructionsAction.java