Search in sources :

Example 1 with CharacterClassType

use of com.evolveum.midpoint.xml.ns._public.common.common_3.CharacterClassType in project midpoint by Evolveum.

the class StringPolicyUtils method normalize.

public static StringPolicyType normalize(StringPolicyType sp) {
    if (null == sp) {
        throw new IllegalArgumentException("Providide string policy cannot be null");
    }
    if (null == sp.getLimitations()) {
        LimitationsType sl = new LimitationsType();
        sl.setCheckAgainstDictionary(false);
        sl.setCheckPattern("");
        sl.setMaxLength(Integer.MAX_VALUE);
        sl.setMinLength(0);
        sl.setMinUniqueChars(0);
        sp.setLimitations(sl);
    }
    // Add default char class
    if (null == sp.getCharacterClass()) {
        CharacterClassType cct = new CharacterClassType();
        cct.setValue(ASCII7_CHARS);
        sp.setCharacterClass(cct);
    }
    return sp;
}
Also used : CharacterClassType(com.evolveum.midpoint.xml.ns._public.common.common_3.CharacterClassType) LimitationsType(com.evolveum.midpoint.xml.ns._public.common.common_3.LimitationsType)

Example 2 with CharacterClassType

use of com.evolveum.midpoint.xml.ns._public.common.common_3.CharacterClassType in project midpoint by Evolveum.

the class ValuePolicyProcessor method generateAttempt.

private String generateAttempt(ValuePolicyType policy, int defaultLength, boolean generateMinimalSize, Context ctx, OperationResult result) {
    StringPolicyType stringPolicy = policy.getStringPolicy();
    // if (policy.getLimitations() != null &&
    // policy.getLimitations().getMinLength() != null){
    // generateMinimalSize = true;
    // }
    // setup default values where missing
    // PasswordPolicyUtils.normalize(pp);
    // Optimize usage of limits ass hashmap of limitas and key is set of
    // valid chars for each limitation
    Map<StringLimitType, List<String>> lims = new HashMap<>();
    int minLen = defaultLength;
    int maxLen = defaultLength;
    int unique = defaultLength / 2;
    if (stringPolicy != null) {
        for (StringLimitType l : stringPolicy.getLimitations().getLimit()) {
            if (null != l.getCharacterClass().getValue()) {
                lims.put(l, StringPolicyUtils.stringTokenizer(l.getCharacterClass().getValue()));
            } else {
                lims.put(l, StringPolicyUtils.stringTokenizer(StringPolicyUtils.collectCharacterClass(stringPolicy.getCharacterClass(), l.getCharacterClass().getRef())));
            }
        }
        // Get global limitations
        minLen = defaultIfNull(stringPolicy.getLimitations().getMinLength(), 0);
        if (minLen != 0 && minLen > defaultLength) {
            defaultLength = minLen;
        }
        maxLen = defaultIfNull(stringPolicy.getLimitations().getMaxLength(), 0);
        unique = defaultIfNull(stringPolicy.getLimitations().getMinUniqueChars(), minLen);
    }
    // test correctness of definition
    if (unique > minLen) {
        minLen = unique;
        OperationResult reportBug = new OperationResult("Global limitation check");
        reportBug.recordWarning("There is more required unique characters then defined minimum. Raise minimum to number of required unique chars.");
    }
    if (minLen == 0 && maxLen == 0) {
        minLen = defaultLength;
        maxLen = defaultLength;
        generateMinimalSize = true;
    }
    if (maxLen == 0) {
        maxLen = Math.max(minLen, defaultLength);
    }
    // Initialize generator
    StringBuilder password = new StringBuilder();
    /*
         * ********************************** Try to find best characters to be
         * first in password
         */
    Map<StringLimitType, List<String>> mustBeFirst = new HashMap<>();
    for (Map.Entry<StringLimitType, List<String>> entry : lims.entrySet()) {
        final StringLimitType key = entry.getKey();
        if (key.isMustBeFirst() != null && key.isMustBeFirst()) {
            mustBeFirst.put(key, entry.getValue());
        }
    }
    // If any limitation was found to be first
    if (!mustBeFirst.isEmpty()) {
        Map<Integer, List<String>> possibleFirstChars = cardinalityCounter(mustBeFirst, null, false, false, result);
        int intersectionCardinality = mustBeFirst.keySet().size();
        List<String> intersectionCharacters = possibleFirstChars.get(intersectionCardinality);
        // If no intersection was found then raise error
        if (null == intersectionCharacters || intersectionCharacters.size() == 0) {
            result.recordFatalError("No intersection for required first character sets in value policy:" + stringPolicy.getDescription());
            // Log error
            if (LOGGER.isErrorEnabled()) {
                LOGGER.error("Unable to generate value for " + ctx.path + ": No intersection for required first character sets in value policy: [" + stringPolicy.getDescription() + "] following character limitation and sets are used:");
                for (Map.Entry<StringLimitType, List<String>> entry : mustBeFirst.entrySet()) {
                    StrBuilder tmp = new StrBuilder();
                    tmp.appendSeparator(", ");
                    tmp.appendAll(entry.getValue());
                    LOGGER.error("L:" + entry.getKey().getDescription() + " -> [" + tmp + "]");
                }
            }
            // EXIT
            return null;
        } else {
            if (LOGGER.isDebugEnabled()) {
                StrBuilder tmp = new StrBuilder();
                tmp.appendSeparator(", ");
                tmp.appendAll(intersectionCharacters);
                LOGGER.trace("Generate first character intersection items [" + tmp + "] into " + ctx.path + ".");
            }
            // Generate random char into password from intersection
            password.append(intersectionCharacters.get(RAND.nextInt(intersectionCharacters.size())));
        }
    }
    /*
         * ************************************** Generate rest to fulfill
         * minimal criteria
         */
    boolean uniquenessReached = false;
    // fake limit with all alphanumeric character, because of number of unique char
    if (lims.isEmpty()) {
        StringLimitType fakeLimit = new StringLimitType();
        CharacterClassType charClass = new CharacterClassType();
        charClass.setValue(ALPHANUMERIC_CHARS);
        fakeLimit.setCharacterClass(charClass);
        fakeLimit.setMustBeFirst(false);
        fakeLimit.setMaxOccurs(maxLen);
        fakeLimit.setMinOccurs(minLen);
        lims.put(fakeLimit, StringPolicyUtils.stringTokenizer(ALPHANUMERIC_CHARS));
    }
    // Count cardinality of elements
    Map<Integer, List<String>> chars;
    for (int i = 0; i < minLen; i++) {
        // Check if still unique chars are needed
        if (password.length() >= unique) {
            uniquenessReached = true;
        }
        // Find all usable characters
        chars = cardinalityCounter(lims, StringPolicyUtils.stringTokenizer(password.toString()), false, uniquenessReached, result);
        // If something goes badly then go out
        if (null == chars) {
            return null;
        }
        if (chars.isEmpty()) {
            LOGGER.trace("Minimal criterias was met. No more characters");
            break;
        }
        // Find lowest possible cardinality and then generate char
        for (int card = 1; card < lims.keySet().size(); card++) {
            if (chars.containsKey(card)) {
                List<String> validChars = chars.get(card);
                password.append(validChars.get(RAND.nextInt(validChars.size())));
                break;
            }
        }
    }
    // test if maximum is not exceeded
    if (password.length() > maxLen) {
        result.recordFatalError("Unable to meet minimal criteria and not exceed maximal size of " + ctx.path + ".");
        return null;
    }
    for (int i = 0; i < minLen; i++) {
        // test if max is reached
        if (password.length() == maxLen) {
            // no more characters maximal size is reached
            break;
        }
        if (password.length() >= minLen && generateMinimalSize) {
            // no more characters are needed
            break;
        }
        // Check if still unique chars are needed
        if (password.length() >= unique) {
            uniquenessReached = true;
        }
        // find all usable characters
        chars = cardinalityCounter(lims, StringPolicyUtils.stringTokenizer(password.toString()), true, uniquenessReached, result);
        // If something goes badly then go out
        if (null == chars) {
            // we hope this never happend.
            result.recordFatalError("No valid characters to generate, but no all limitation are reached");
            return null;
        }
        // our work
        if (chars.isEmpty()) {
            if (i == 0) {
                password.append(RandomStringUtils.randomAlphanumeric(minLen));
            }
            break;
        // if (!StringUtils.isBlank(password.toString()) &&
        // password.length() >= minLen) {
        // break;
        // }
        // check uf this is a firs cycle and if we need to user some
        // default (alphanum) character class.
        }
        // Find lowest possible cardinality and then generate char
        for (int card = 1; card <= lims.keySet().size(); card++) {
            if (chars.containsKey(card)) {
                List<String> validChars = chars.get(card);
                password.append(validChars.get(RAND.nextInt(validChars.size())));
                break;
            }
        }
    }
    if (password.length() < minLen) {
        result.recordFatalError("Unable to generate value for " + ctx.path + " and meet minimal size of " + ctx.path + ". Actual length: " + password.length() + ", required: " + minLen);
        LOGGER.trace("Unable to generate value for " + ctx.path + " and meet minimal size of " + ctx.path + ". Actual length: {}, required: {}", password.length(), minLen);
        return null;
    }
    result.recordSuccess();
    // Shuffle output to solve pattern like output
    StrBuilder sb = new StrBuilder(password.substring(0, 1));
    List<String> shuffleBuffer = StringPolicyUtils.stringTokenizer(password.substring(1));
    Collections.shuffle(shuffleBuffer);
    sb.appendAll(shuffleBuffer);
    return sb.toString();
}
Also used : StringPolicyType(com.evolveum.midpoint.xml.ns._public.common.common_3.StringPolicyType) CharacterClassType(com.evolveum.midpoint.xml.ns._public.common.common_3.CharacterClassType) OperationResult(com.evolveum.midpoint.schema.result.OperationResult) StringLimitType(com.evolveum.midpoint.xml.ns._public.common.common_3.StringLimitType) LocalizableMessageList(com.evolveum.midpoint.util.LocalizableMessageList) VariablesMap(com.evolveum.midpoint.schema.expression.VariablesMap) StrBuilder(org.apache.commons.lang.text.StrBuilder)

Example 3 with CharacterClassType

use of com.evolveum.midpoint.xml.ns._public.common.common_3.CharacterClassType in project midpoint by Evolveum.

the class StringPolicyUtils method collectCharacterClass.

/**
 * Prepare usable list of strings for generator
 */
public static String collectCharacterClass(CharacterClassType cc, QName ref) {
    StrBuilder l = new StrBuilder();
    if (null == cc) {
        throw new IllegalArgumentException("Character class cannot be null");
    }
    if (null != cc.getValue() && (null == ref || ref.equals(cc.getName()))) {
        l.append(cc.getValue());
    } else if (null != cc.getCharacterClass() && !cc.getCharacterClass().isEmpty()) {
        // Process all sub lists
        for (CharacterClassType subClass : cc.getCharacterClass()) {
            // If we found requested name or no name defined
            if (null == ref || ref.equals(cc.getName())) {
                l.append(collectCharacterClass(subClass, null));
            } else {
                l.append(collectCharacterClass(subClass, ref));
            }
        }
    }
    // Remove duplicity in return;
    HashSet<String> h = new HashSet<>();
    for (String s : l.toString().split("")) {
        h.add(s);
    }
    return new StrBuilder().appendAll(h).toString();
}
Also used : CharacterClassType(com.evolveum.midpoint.xml.ns._public.common.common_3.CharacterClassType) StrBuilder(org.apache.commons.lang.text.StrBuilder) HashSet(java.util.HashSet)

Aggregations

CharacterClassType (com.evolveum.midpoint.xml.ns._public.common.common_3.CharacterClassType)3 StrBuilder (org.apache.commons.lang.text.StrBuilder)2 VariablesMap (com.evolveum.midpoint.schema.expression.VariablesMap)1 OperationResult (com.evolveum.midpoint.schema.result.OperationResult)1 LocalizableMessageList (com.evolveum.midpoint.util.LocalizableMessageList)1 LimitationsType (com.evolveum.midpoint.xml.ns._public.common.common_3.LimitationsType)1 StringLimitType (com.evolveum.midpoint.xml.ns._public.common.common_3.StringLimitType)1 StringPolicyType (com.evolveum.midpoint.xml.ns._public.common.common_3.StringPolicyType)1 HashSet (java.util.HashSet)1