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;
}
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();
}
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();
}
Aggregations