Skip to content

Commit

Permalink
Merge branch 'master' of https://github.com/Evolveum/midpoint
Browse files Browse the repository at this point in the history
  • Loading branch information
katkav committed Dec 12, 2017
2 parents 2874d21 + 751e5a3 commit bc06c15
Show file tree
Hide file tree
Showing 22 changed files with 286 additions and 116 deletions.
2 changes: 0 additions & 2 deletions dist/src/main/bin/midpoint.sh
Expand Up @@ -23,8 +23,6 @@ fi
JAVA_OPTS="$JAVA_OPTS
-Xms2048M
-Xmx2048M
-XX:PermSize=128m
-XX:MaxPermSize=256m
-Dpython.cachedir=$MIDPOINT_HOME/tmp
-Djavax.net.ssl.trustStore=$MIDPOINT_HOME/keystore.jceks
-Djavax.net.ssl.trustStoreType=jceks
Expand Down
Expand Up @@ -36,6 +36,7 @@
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import java.util.stream.StreamSupport;

Expand All @@ -45,6 +46,7 @@
import javax.xml.namespace.QName;

import com.evolveum.midpoint.gui.api.SubscriptionType;
import com.evolveum.midpoint.gui.api.model.ReadOnlyModel;
import com.evolveum.midpoint.model.api.ModelExecuteOptions;
import com.evolveum.midpoint.schema.GetOperationOptions;
import com.evolveum.midpoint.schema.SelectorOptions;
Expand Down Expand Up @@ -682,6 +684,14 @@ public List<T> getObject() {
};
}

@NotNull
public static <T extends Enum> IModel<List<T>> createReadonlyModelFromEnum(@NotNull Class<T> type, @NotNull Predicate<T> filter) {
return new ReadOnlyModel<>(() ->
Arrays.stream(type.getEnumConstants())
.filter(filter)
.collect(Collectors.toList()));
}

public static List<String> createTaskCategoryList() {
List<String> categories = new ArrayList<>();

Expand Down
Expand Up @@ -69,7 +69,7 @@ protected void initLayout() {
createStringResource("ObjectType.description"), ID_LABEL_SIZE, ID_INPUT_SIZE, false);
add(description);

IModel choices = WebComponentUtil.createReadonlyModelFromEnum(ExportType.class);
IModel choices = WebComponentUtil.createReadonlyModelFromEnum(ExportType.class, e -> e != ExportType.JXL);
IChoiceRenderer renderer = new EnumChoiceRenderer();
DropDownFormGroup exportType = new DropDownFormGroup(ID_EXPORT_TYPE, new PropertyModel<ExportType>(getModel(), ReportDto.F_EXPORT_TYPE), choices, renderer,
createStringResource("ReportType.export"), ID_LABEL_SIZE, ID_INPUT_SIZE, true);
Expand Down
36 changes: 30 additions & 6 deletions infra/prism/src/main/java/com/evolveum/midpoint/prism/Item.java
Expand Up @@ -812,15 +812,20 @@ public boolean hasRaw() {
}

public boolean isEmpty() {
return getValues().isEmpty();
return hasNoValues();
}

@Override
public boolean hasNoValues() {
return getValues().isEmpty();
}

public static boolean hasNoValues(Item<?, ?> item) {
return item == null || item.getValues().isEmpty();
}

@Override
public int hashCode() {
int valuesHash = 0;
if (values != null) {
valuesHash = MiscUtil.unorderedCollectionHashcode(values, null);
}
int valuesHash = MiscUtil.unorderedCollectionHashcode(values, null);
if (valuesHash == 0) {
// empty or non-significant container. We do not want this to destroy hashcode of
// parent item
Expand Down Expand Up @@ -1024,4 +1029,23 @@ public void modifyUnfrozen(Runnable mutator) {
}
}
}

@NotNull
public static <V extends PrismValue> Collection<V> getValues(Item<V, ?> item) {
return item != null ? item.getValues() : Collections.emptySet();
}

// Path may contain ambiguous segments (e.g. assignment/targetRef when there are more assignments)
// Note that the path can contain name segments only (at least for now)
@NotNull
public Collection<PrismValue> getAllValues(ItemPath path) {
return values.stream()
.flatMap(v -> v.getAllValues(path).stream())
.collect(Collectors.toList());
}

@NotNull
public static Collection<PrismValue> getAllValues(Item<?, ?> item, ItemPath path) {
return item != null ? item.getAllValues(path) : Collections.emptySet();
}
}
Expand Up @@ -674,7 +674,7 @@ public ContainerDelta<C> createDelta(ItemPath path) {
}

public boolean isEmpty() {
for(PrismContainerValue<C> pval : getValues()) {
for (PrismContainerValue<C> pval : getValues()) {
if (!pval.isEmpty()) {
return false;
}
Expand Down
Expand Up @@ -25,13 +25,7 @@
import org.jetbrains.annotations.Nullable;

import javax.xml.namespace.QName;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.*;
import java.util.function.Function;

import static java.util.Collections.emptySet;
Expand Down Expand Up @@ -524,7 +518,6 @@ public static PrismValue fromRealValue(Object realValue) {
}
}


// Path may contain ambiguous segments (e.g. assignment/targetRef when there are more assignments)
// Note that the path can contain name segments only (at least for now)
@NotNull
Expand Down
Expand Up @@ -830,6 +830,7 @@ public static <DD extends ItemDelta> DD findItemDelta(Collection<? extends ItemD
if (deltaType.isAssignableFrom(delta.getClass()) && delta.getPath().equivalent(propertyPath)) {
return (DD) delta;
}
// e.g. when deleting credentials we match also deletion of credentials/password (is that correct?)
if ((delta instanceof ContainerDelta<?>) && delta.getPath().isSubPath(propertyPath)) {
return (DD) ((ContainerDelta)delta).getSubDelta(propertyPath.substract(delta.getPath()));
}
Expand Down
Expand Up @@ -494,6 +494,7 @@ Credentials.securityQuestions=security questions
ValuePolicy.minAgeNotReached=Minimal age was not yet reached.
ValuePolicy.valueRecentlyUsed=The value was recently used.
ValuePolicy.valueMustBePresent=The value must be present.
ValuePolicy.valuesMustBePresent=At least {0} values must be present. Actual number of values: {1}.
ValuePolicy.minimalSizeNotMet=Minimal size ({0}) is not met (actual length: {1}).
ValuePolicy.maximalSizeExceeded=Maximal size ({0}) was exceeded (actual length: {1}).
ValuePolicy.minimalUniqueCharactersNotMet=Minimal count of unique characters ({0}) is not met (unique characters: {1}).
Expand Down Expand Up @@ -675,4 +676,4 @@ relation.approver=approver
relation.owner=owner
relation.consent=consent
AbstractCredentialType.forceChange=Force change on next login
PasswordType.value=Password value
PasswordType.value=Value
Expand Up @@ -11600,7 +11600,7 @@
<xsd:element name="minOccurs" type="xsd:string" minOccurs="0" default="0">
<xsd:annotation>
<xsd:documentation>
Minimal number of value occurences. minOccurs set to zero means that the value
Minimal number of value occurrences. minOccurs set to zero means that the value
is optional.
E.g. when applied to passwords the minOccurs=0 means that the policy will
accept no password at all. But it will still validate the password using
Expand All @@ -11615,7 +11615,7 @@
<xsd:element name="maxOccurs" type="xsd:string" minOccurs="0">
<xsd:annotation>
<xsd:documentation>
Maximal number of value occurences.
Maximal number of value occurrences.
If not specified then the default schema limitation is imposed.
DEPRECATED. Use equivalent setting in security policy instead.
</xsd:documentation>
Expand Down Expand Up @@ -14512,7 +14512,7 @@
<xsd:element name="minOccurs" type="xsd:string" minOccurs="0" default="0">
<xsd:annotation>
<xsd:documentation>
Minimal number of value occurences. minOccurs set to zero means that the value
Minimal number of value occurrences. minOccurs set to zero means that the value
is optional.
E.g. when applied to passwords the minOccurs=0 means that the policy will
accept no password at all. But it will still validate the password using
Expand Down
Expand Up @@ -687,4 +687,9 @@ public static <T> Collection<T> filter(Collection<T> input, Predicate<? super T>
public static <T> Set<T> filter(Set<T> input, Predicate<? super T> predicate) {
return input.stream().filter(predicate).collect(Collectors.toSet());
}

@NotNull
public static <V> Collection<V> nonNullValues(@NotNull Collection<V> values) {
return values.stream().filter(Objects::nonNull).collect(Collectors.toList());
}
}
Expand Up @@ -57,6 +57,9 @@
import com.evolveum.midpoint.xml.ns._public.common.common_3.UserType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.ValuePolicyType;
import com.evolveum.prism.xml.ns._public.types_3.ProtectedStringType;
import org.jetbrains.annotations.NotNull;

import static org.apache.commons.lang3.ObjectUtils.defaultIfNull;

/**
* Evaluator that validates the value of any object property. The validation means a checks whether
Expand Down Expand Up @@ -179,11 +182,13 @@ public void setTask(Task task) {
this.task = task;
}

// Beware: minOccurs is not checked here; it has to be done globally over all values. See validateMinOccurs method.
public OperationResult validateProtectedStringValue(ProtectedStringType value) throws SchemaException, ObjectNotFoundException, ExpressionEvaluationException, CommunicationException, ConfigurationException, SecurityViolationException {
String clearValue = getClearValue(value);
return validateStringValue(clearValue);
}

// Beware: minOccurs is not checked here; it has to be done globally over all values. See validateMinOccurs method.
public OperationResult validateStringValue(String clearValue) throws SchemaException, ObjectNotFoundException, ExpressionEvaluationException, CommunicationException, ConfigurationException, SecurityViolationException {
OperationResult result = new OperationResult(OPERATION_VALIDATE_VALUE);
List<LocalizableMessage> messages = new ArrayList<>();
Expand All @@ -194,6 +199,11 @@ public OperationResult validateStringValue(String clearValue) throws SchemaExcep
validateHistory(clearValue, messages, result);
validateStringPolicy(clearValue, messages, result);

return generateResultMessage(messages, result);
}

@NotNull
private OperationResult generateResultMessage(List<LocalizableMessage> messages, OperationResult result) {
result.computeStatus();
if (!result.isSuccess() && !messages.isEmpty()) {
result.setUserFriendlyMessage(
Expand All @@ -205,6 +215,17 @@ public OperationResult validateStringValue(String clearValue) throws SchemaExcep
return result;
}

public OperationResult validateMinOccurs(int values) throws SchemaException {
OperationResult result = new OperationResult(OPERATION_VALIDATE_VALUE);
List<LocalizableMessage> messages = new ArrayList<>();

prepare();

validateMinOccurs(values, messages, result);

return generateResultMessage(messages, result);
}

private void prepare() throws SchemaException {
if (!prepared) {
preparePassword();
Expand Down Expand Up @@ -284,15 +305,7 @@ private void validateStringPolicy(String clearValue, List<LocalizableMessage> me
ObjectNotFoundException, ExpressionEvaluationException, CommunicationException, ConfigurationException, SecurityViolationException {

if (clearValue == null) {
int minOccurs = getMinOccurs();
if (minOccurs == 0) {
return;
} else {
LocalizableMessage msg = LocalizableMessageBuilder.buildKey("ValuePolicy.valueMustBePresent");
result.addSubresult(new OperationResult("minOccurs", OperationResultStatus.FATAL_ERROR, msg));
messages.add(msg);
return;
}
return; // should be checked elsewhere
}

if (valuePolicy == null) {
Expand All @@ -304,6 +317,23 @@ private void validateStringPolicy(String clearValue, List<LocalizableMessage> me
"user " + shortDesc + " value policy validation", task, result);
}

private void validateMinOccurs(int values, List<LocalizableMessage> messages, OperationResult result) {
int minOccurs = getMinOccurs();
if (values < minOccurs) { // implies minOccurs > 0
LocalizableMessage msg;
if (minOccurs == 1) {
msg = LocalizableMessageBuilder.buildKey("ValuePolicy.valueMustBePresent");
} else {
msg = new LocalizableMessageBuilder()
.key("ValuePolicy.valuesMustBePresent")
.args(minOccurs, values)
.build();
}
result.addSubresult(new OperationResult("minOccurs", OperationResultStatus.FATAL_ERROR, msg));
messages.add(msg);
}
}

private void validateHistory(String clearValue, List<LocalizableMessage> messages, OperationResult result) throws SchemaException {

if (!QNameUtil.match(CredentialsType.F_PASSWORD, credentialQName)) {
Expand Down Expand Up @@ -364,11 +394,12 @@ private int getMinOccurs() {
if (credentialPolicy == null) {
return 0;
}
String minOccurs = credentialPolicy.getMinOccurs();
if (minOccurs == null) {
return 0;
String minOccursPhrase = credentialPolicy.getMinOccurs();
if (minOccursPhrase == null && valuePolicy != null) {
minOccursPhrase = valuePolicy.getMinOccurs(); // deprecated but let's consider it
}
return XsdTypeMapper.multiplicityToInteger(minOccurs);
Integer minOccurs = XsdTypeMapper.multiplicityToInteger(minOccursPhrase);
return defaultIfNull(minOccurs, 0);
}

private List<PasswordHistoryEntryType> getSortedHistoryList(PrismContainer<PasswordHistoryEntryType> historyEntries, boolean ascending) {
Expand Down
Expand Up @@ -193,7 +193,7 @@ private <O extends ObjectType> Response generateValue(PrismObject<O> object, Pol
return response;
}

@POST
@POST
@Path("/{type}/{oid}/validate")
@Consumes({"application/xml", "application/json", "application/yaml"})
@Produces({"application/xml", "application/json", "application/yaml"})
Expand Down
Expand Up @@ -248,8 +248,13 @@ protected Class<? extends ObjectType> getType(Task task) {
@Override
protected ObjectQuery createQuery(SynchronizeAccountResultHandler handler, TaskRunResult runResult, Task task, OperationResult opResult) {
try {
return ObjectQueryUtil.createResourceAndObjectClassQuery(handler.getResourceOid(),
handler.getObjectClass().getTypeName(), prismContext);
ObjectQuery query = createQueryFromTaskIfExists(handler, runResult, task, opResult);
if (query != null) {
return query;
} else {
return ObjectQueryUtil.createResourceAndObjectClassQuery(handler.getResourceOid(),
handler.getObjectClass().getTypeName(), prismContext);
}
} catch (SchemaException e) {
LOGGER.error("Import: Schema error during creating search query: {}",e.getMessage());
opResult.recordFatalError("Schema error during creating search query: "+e.getMessage(),e);
Expand Down

0 comments on commit bc06c15

Please sign in to comment.