Search in sources :

Example 1 with RecoveryScenarios

use of org.wso2.carbon.identity.recovery.RecoveryScenarios in project identity-governance by wso2-extensions.

the class UserAccountRecoveryManager method addRecoveryDataObject.

/**
 * Add the notification channel recovery data to the store.
 *
 * @param username     Username
 * @param tenantDomain Tenant domain
 * @param secretKey    RecoveryId
 * @param scenario     RecoveryScenario
 * @param recoveryData Data to be stored as mata which are needed to evaluate the recovery data object
 * @throws IdentityRecoveryServerException If an error occurred while storing recovery data.
 */
private void addRecoveryDataObject(String username, String tenantDomain, String secretKey, RecoveryScenarios scenario, String recoveryData) throws IdentityRecoveryServerException {
    // Create a user object.
    User user = Utils.buildUser(username, tenantDomain);
    UserRecoveryData recoveryDataDO = new UserRecoveryData(user, secretKey, scenario, RecoverySteps.SEND_RECOVERY_INFORMATION);
    // Store available channels in remaining setIDs.
    recoveryDataDO.setRemainingSetIds(recoveryData);
    try {
        UserRecoveryDataStore userRecoveryDataStore = JDBCRecoveryDataStore.getInstance();
        userRecoveryDataStore.invalidate(user);
        userRecoveryDataStore.store(recoveryDataDO);
    } catch (IdentityRecoveryException e) {
        throw Utils.handleServerException(IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_ERROR_STORING_RECOVERY_DATA, "Error Storing Recovery Data", e);
    }
}
Also used : User(org.wso2.carbon.identity.application.common.model.User) UserRecoveryData(org.wso2.carbon.identity.recovery.model.UserRecoveryData) UserRecoveryDataStore(org.wso2.carbon.identity.recovery.store.UserRecoveryDataStore) IdentityRecoveryException(org.wso2.carbon.identity.recovery.IdentityRecoveryException)

Example 2 with RecoveryScenarios

use of org.wso2.carbon.identity.recovery.RecoveryScenarios in project identity-governance by wso2-extensions.

the class UserAccountRecoveryManager method isFunctionalityLocked.

/**
 * Verify whether the functionality is locked or not and return true if it is locked. Else return false.
 *
 * @param username          Username.
 * @param tenantDomain      TenantDomain.
 * @param channelType       ChannelType (SMS or EMail).
 * @param recoveryScenarios RecoveryScenarios.
 * @return Return true if it is locked. Else return false.
 * @throws IdentityRecoveryServerException
 */
private boolean isFunctionalityLocked(String username, String tenantDomain, String channelType, RecoveryScenarios recoveryScenarios) throws IdentityRecoveryServerException {
    if (PER_USER_FUNCTIONALITY_LOCKING_ENABLED) {
        String functionalityType = FUNCTIONALITY_PREFIX + recoveryScenarios.name() + "_" + channelType;
        // for recovery.
        if (IdentityRecoveryConstants.FunctionalityTypes.getFunctionality(functionalityType) != null) {
            String functionalityIdentifier = IdentityRecoveryConstants.FunctionalityTypes.getFunctionality(functionalityType).getFunctionalityIdentifier();
            FunctionalityLockStatus functionalityLockStatus = getFunctionalityStatusOfUser(username, tenantDomain, functionalityIdentifier);
            return functionalityLockStatus.getLockStatus();
        }
    }
    return false;
}
Also used : FunctionalityLockStatus(org.wso2.carbon.identity.user.functionality.mgt.model.FunctionalityLockStatus)

Example 3 with RecoveryScenarios

use of org.wso2.carbon.identity.recovery.RecoveryScenarios in project identity-governance by wso2-extensions.

the class UserAccountRecoveryManager method retrieveUserRecoveryInformation.

/**
 * Initiate the recovery flow for the user with matching claims.
 *
 * @param claims           User claims
 * @param tenantDomain     Tenant domain
 * @param recoveryScenario Recovery scenario
 * @param properties       Meta properties
 * @return RecoveryChannelInfoDTO object.
 */
public RecoveryChannelInfoDTO retrieveUserRecoveryInformation(Map<String, String> claims, String tenantDomain, RecoveryScenarios recoveryScenario, Map<String, String> properties) throws IdentityRecoveryException {
    // Retrieve the user who matches the given set of claims.
    String username = getUsernameByClaims(claims, tenantDomain);
    if (StringUtils.isNotEmpty(username)) {
        User user = Utils.buildUser(username, tenantDomain);
        // If the account is locked or disabled, do not let the user to recover the account.
        checkAccountLockedStatus(user);
        List<NotificationChannel> notificationChannels;
        // Get the notification management mechanism.
        boolean isNotificationsInternallyManaged = Utils.isNotificationsInternallyManaged(tenantDomain, properties);
        /* If the notification is internally managed, then notification channels available for the user needs to
            be retrieved. If external notifications are enabled, external channel list should be returned.*/
        if (isNotificationsInternallyManaged) {
            notificationChannels = getInternalNotificationChannelList(username, tenantDomain, recoveryScenario);
        } else {
            notificationChannels = getExternalNotificationChannelList();
        }
        // Validate whether the user account is eligible for account recovery.
        checkUserValidityForAccountRecovery(user, recoveryScenario, notificationChannels, properties);
        // This flow will be initiated only if the user has any verified channels.
        NotificationChannelDTO[] notificationChannelDTOS = getNotificationChannelsResponseDTOList(tenantDomain, notificationChannels);
        UserRecoveryDataStore userRecoveryDataStore = JDBCRecoveryDataStore.getInstance();
        // Get the existing RESEND_CONFIRMATION_CODE details if there is any.
        UserRecoveryData recoveryDataDO = userRecoveryDataStore.loadWithoutCodeExpiryValidation(user, recoveryScenario, RecoverySteps.RESEND_CONFIRMATION_CODE);
        String recoveryCode = UUIDGenerator.generateUUID();
        String notificationChannelList = getNotificationChannelListForRecovery(notificationChannels);
        /* Check whether the existing confirmation code can be used based on the email confirmation code tolerance
               with the extracted RESEND_CONFIRMATION_CODE details. */
        if (Utils.reIssueExistingConfirmationCode(recoveryDataDO, NotificationChannels.EMAIL_CHANNEL.getChannelType())) {
            /* Update the existing RESEND_CONFIRMATION_CODE details with new code details without changing the
                   time created of the RESEND_CONFIRMATION_CODE. */
            userRecoveryDataStore.invalidateWithoutChangeTimeCreated(recoveryDataDO.getSecret(), recoveryCode, RecoverySteps.SEND_RECOVERY_INFORMATION, notificationChannelList);
        } else {
            addRecoveryDataObject(username, tenantDomain, recoveryCode, recoveryScenario, notificationChannelList);
        }
        return buildUserRecoveryInformationResponseDTO(username, recoveryCode, notificationChannelDTOS);
    } else {
        if (log.isDebugEnabled()) {
            log.debug("No valid user found for the given claims");
        }
        throw Utils.handleClientException(IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_NO_USER_FOUND, null);
    }
}
Also used : NotificationChannel(org.wso2.carbon.identity.recovery.model.NotificationChannel) User(org.wso2.carbon.identity.application.common.model.User) NotificationChannelDTO(org.wso2.carbon.identity.recovery.dto.NotificationChannelDTO) UserRecoveryData(org.wso2.carbon.identity.recovery.model.UserRecoveryData) UserRecoveryDataStore(org.wso2.carbon.identity.recovery.store.UserRecoveryDataStore)

Example 4 with RecoveryScenarios

use of org.wso2.carbon.identity.recovery.RecoveryScenarios in project identity-governance by wso2-extensions.

the class UserAccountRecoveryManager method checkUserValidityForAccountRecovery.

/**
 * Check whether the user account is eligible for account recovery.
 *
 * @param user                         The user.
 * @param recoveryScenario             Account recovery scenario.
 * @param recoveryNotificationChannels Notification channel.
 * @param metaProperties               Meta details.
 * @throws IdentityRecoveryException If account doesn't satisfy the conditions to recover.
 */
private void checkUserValidityForAccountRecovery(User user, RecoveryScenarios recoveryScenario, List<NotificationChannel> recoveryNotificationChannels, Map<String, String> metaProperties) throws IdentityRecoveryException {
    HashMap<String, Object> properties = new HashMap<>();
    properties.put(IdentityEventConstants.EventProperty.USER, user);
    properties.put(IdentityEventConstants.EventProperty.USER_STORE_MANAGER, getUserStoreManager(user));
    properties.put(IdentityEventConstants.EventProperty.RECOVERY_SCENARIO, recoveryScenario);
    properties.put(IdentityEventConstants.EventProperty.NOTIFICATION_CHANNEL, recoveryNotificationChannels);
    if (MapUtils.isNotEmpty(metaProperties)) {
        for (Map.Entry<String, String> metaProperty : metaProperties.entrySet()) {
            if (StringUtils.isNotBlank(metaProperty.getValue()) && StringUtils.isNotBlank(metaProperty.getKey())) {
                properties.put(metaProperty.getKey(), metaProperty.getValue());
            }
        }
    }
    Event identityMgtEvent = new Event(IdentityEventConstants.Event.PRE_ACCOUNT_RECOVERY, properties);
    try {
        IdentityRecoveryServiceDataHolder.getInstance().getIdentityEventService().handleEvent(identityMgtEvent);
    } catch (IdentityEventException e) {
        if (log.isDebugEnabled()) {
            log.debug("Error occurred while validating user account " + user.getUserName() + " for account recovery.");
        }
        String errorMessage = e.getMessage();
        String errorCode = IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_USER_ACCOUNT_RECOVERY_VALIDATION_FAILED.getCode();
        if (USERNAME_RECOVERY.equals(recoveryScenario)) {
            errorCode = IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_USERNAME_RECOVERY_VALIDATION_FAILED.getCode();
        } else if (NOTIFICATION_BASED_PW_RECOVERY.equals(recoveryScenario) || QUESTION_BASED_PWD_RECOVERY.equals(recoveryScenario)) {
            errorCode = IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_PASSWORD_RECOVERY_VALIDATION_FAILED.getCode();
        }
        throw Utils.handleClientException(errorCode, errorMessage, user.getUserName());
    }
}
Also used : HashMap(java.util.HashMap) IdentityEventException(org.wso2.carbon.identity.event.IdentityEventException) Event(org.wso2.carbon.identity.event.event.Event) HashMap(java.util.HashMap) Map(java.util.Map)

Example 5 with RecoveryScenarios

use of org.wso2.carbon.identity.recovery.RecoveryScenarios in project identity-governance by wso2-extensions.

the class JDBCRecoveryDataStore method load.

@Override
public UserRecoveryData load(User user) throws IdentityRecoveryException {
    handleRecoveryDataEventPublishing(PRE_GET_USER_RECOVERY_DATA, GET_USER_RECOVERY_DATA_SCENARIO_WITH_CODE_EXPIRY_VALIDATION, null, null, null, user, new UserRecoveryData(user, null, null, null));
    PreparedStatement prepStmt = null;
    ResultSet resultSet = null;
    Connection connection = IdentityDatabaseUtil.getDBConnection(false);
    String code = null;
    UserRecoveryData userRecoveryData = null;
    Boolean isOperationSuccess = false;
    Enum description = ERROR_CODE_RECOVERY_DATA_NOT_FOUND_FOR_USER;
    try {
        String sql;
        if (IdentityUtil.isUserStoreCaseSensitive(user.getUserStoreDomain(), IdentityTenantUtil.getTenantId(user.getTenantDomain()))) {
            sql = IdentityRecoveryConstants.SQLQueries.LOAD_RECOVERY_DATA_OF_USER;
        } else {
            sql = IdentityRecoveryConstants.SQLQueries.LOAD_RECOVERY_DATA_OF_USER_CASE_INSENSITIVE;
        }
        prepStmt = connection.prepareStatement(sql);
        prepStmt.setString(1, user.getUserName());
        prepStmt.setString(2, user.getUserStoreDomain().toUpperCase());
        prepStmt.setInt(3, IdentityTenantUtil.getTenantId(user.getTenantDomain()));
        resultSet = prepStmt.executeQuery();
        if (resultSet.next()) {
            Timestamp timeCreated = resultSet.getTimestamp("TIME_CREATED", Calendar.getInstance(TimeZone.getTimeZone(UTC)));
            RecoveryScenarios scenario = RecoveryScenarios.valueOf(resultSet.getString("SCENARIO"));
            RecoverySteps step = RecoverySteps.valueOf(resultSet.getString("STEP"));
            code = resultSet.getString("CODE");
            String remainingSets = resultSet.getString("REMAINING_SETS");
            userRecoveryData = new UserRecoveryData(user, code, scenario, step);
            if (isCodeExpired(user.getTenantDomain(), scenario, step, timeCreated.getTime(), remainingSets)) {
                isOperationSuccess = false;
                description = ERROR_CODE_EXPIRED_CODE;
                throw Utils.handleClientException(ERROR_CODE_EXPIRED_CODE, code);
            }
            if (StringUtils.isNotBlank(remainingSets)) {
                userRecoveryData.setRemainingSetIds(resultSet.getString("REMAINING_SETS"));
            }
            isOperationSuccess = true;
            description = null;
            return userRecoveryData;
        }
    } catch (SQLException e) {
        isOperationSuccess = false;
        description = ERROR_CODE_UNEXPECTED;
        throw Utils.handleServerException(ERROR_CODE_UNEXPECTED, null, e);
    } finally {
        handleRecoveryDataEventPublishing(POST_GET_USER_RECOVERY_DATA, GET_USER_RECOVERY_DATA_SCENARIO_WITH_CODE_EXPIRY_VALIDATION, isOperationSuccess, description, code, user, userRecoveryData);
        IdentityDatabaseUtil.closeAllConnections(connection, resultSet, prepStmt);
    }
    return null;
}
Also used : RecoveryScenarios(org.wso2.carbon.identity.recovery.RecoveryScenarios) RecoverySteps(org.wso2.carbon.identity.recovery.RecoverySteps) UserRecoveryData(org.wso2.carbon.identity.recovery.model.UserRecoveryData) SQLException(java.sql.SQLException) ResultSet(java.sql.ResultSet) Connection(java.sql.Connection) PreparedStatement(java.sql.PreparedStatement) Timestamp(java.sql.Timestamp)

Aggregations

UserRecoveryData (org.wso2.carbon.identity.recovery.model.UserRecoveryData)7 RecoveryScenarios (org.wso2.carbon.identity.recovery.RecoveryScenarios)4 RecoverySteps (org.wso2.carbon.identity.recovery.RecoverySteps)4 UserRecoveryDataStore (org.wso2.carbon.identity.recovery.store.UserRecoveryDataStore)4 Connection (java.sql.Connection)3 PreparedStatement (java.sql.PreparedStatement)3 ResultSet (java.sql.ResultSet)3 SQLException (java.sql.SQLException)3 Timestamp (java.sql.Timestamp)3 User (org.wso2.carbon.identity.application.common.model.User)3 IdentityRecoveryException (org.wso2.carbon.identity.recovery.IdentityRecoveryException)2 NotificationChannel (org.wso2.carbon.identity.recovery.model.NotificationChannel)2 ArrayList (java.util.ArrayList)1 HashMap (java.util.HashMap)1 Map (java.util.Map)1 IdentityEventException (org.wso2.carbon.identity.event.IdentityEventException)1 Event (org.wso2.carbon.identity.event.event.Event)1 NotificationChannels (org.wso2.carbon.identity.governance.service.notification.NotificationChannels)1 NotificationChannelDTO (org.wso2.carbon.identity.recovery.dto.NotificationChannelDTO)1 ResendConfirmationDTO (org.wso2.carbon.identity.recovery.dto.ResendConfirmationDTO)1