Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/master'
Browse files Browse the repository at this point in the history
  • Loading branch information
mederly committed Jun 15, 2016
2 parents 63fad92 + 0336df4 commit 9a9dd2f
Show file tree
Hide file tree
Showing 18 changed files with 138 additions and 59 deletions.
Expand Up @@ -177,10 +177,6 @@ private void onRemovePassword(IModel<ProtectedStringType> model, AjaxRequestTarg
get(ID_LINK_CONTAINER).get(ID_PASSWORD_REMOVE).setVisible(true);
passwordInputVisble = false;
target.add(this);

ProtectedStringType newValue = new ProtectedStringType();
byte[] temp = new byte[0];
newValue.setClearBytes(temp);
model.setObject(null);
}

Expand Down Expand Up @@ -263,10 +259,14 @@ public String getObject() {

@Override
public void setObject(String object) {
if (psModel.getObject() == null) {
psModel.setObject(new ProtectedStringType());
if (object == null) {
psModel.setObject(null);
} else {
if (psModel.getObject() == null) {
psModel.setObject(new ProtectedStringType());
}
psModel.getObject().setClearValue(object);
}
psModel.getObject().setClearValue(object);
}

}
Expand Down
Expand Up @@ -512,7 +512,10 @@ public boolean isVisible() {

@Override
public void onClick(AjaxRequestTarget target) {
model.getObject().setShowError(!model.getObject().isShowError());
OpResult result = OperationResultPanel.this.getModelObject();
result.setShowError(!model.getObject().isShowError());
result.setAlreadyShown(false); // hack to be able to expand/collapse OpResult after rendered.
// model.getObject().setShowError(!model.getObject().isShowError());
target.add(OperationResultPanel.this);
}

Expand Down
Expand Up @@ -44,9 +44,7 @@ public class PropertyWrapper<I extends Item<? extends PrismValue, ID>, ID extend
public PropertyWrapper(@Nullable ContainerWrapper container, I property, boolean readonly, ValueStatus status) {
super(container, property, readonly, status);

ItemPath passwordPath = new ItemPath(SchemaConstantsGenerated.C_CREDENTIALS,
CredentialsType.F_PASSWORD);
if (container != null && passwordPath.equivalent(container.getPath())
if (container != null && SchemaConstants.PATH_PASSWORD.equivalent(container.getPath())
&& PasswordType.F_VALUE.equals(property.getElementName())) {
super.setDisplayName("prismPropertyPanel.name.credentials.password");
}
Expand Down

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Expand Up @@ -2355,7 +2355,7 @@ SchemaHandlingStep.activation.tooltip.inbound=Inbound mappings map values from t
SchemaHandlingStep.activation.tooltip.outbound=Outbound mappings map values from Identity Manager (usually a user) to the resource (usually an account).
SchemaHandlingStep.association.label.associationName=Association name
SchemaHandlingStep.association.label.associationNamespace=Namespace
SchemaHandlingStep.association.tooltip.associationAttribute=Name of the attribute that "holds" the association. I.e. an attribute which contains the identifier of the associated object. This is usually an attribute such as "memeber", "groups", "roles", etc. In subject-to-object associations this is an attribute of a subject (e.g. account attribute "groups"). In object-to-subject associations this is an attribute of an object (e.g. group attribute "members").
SchemaHandlingStep.association.tooltip.associationAttribute=Name of the attribute that "holds" the association. I.e. an attribute which contains the identifier of the associated object. This is usually an attribute such as "member", "groups", "roles", etc. In subject-to-object associations this is an attribute of a subject (e.g. account attribute "groups"). In object-to-subject associations this is an attribute of an object (e.g. group attribute "members").
SchemaHandlingStep.association.tooltip.associationLocalPart=TODO\: SchemaHandlingStep.association.tooltip.associationLocalPart
SchemaHandlingStep.association.tooltip.associationNamespace=TODO\: SchemaHandlingStep.association.tooltip.associationNamespace
SchemaHandlingStep.association.tooltip.direction=Defines the direction of the association. Object-to-subject\: Object (e.g. group) has an attribute that contains identifier of the subject (e.g. account); Subject-to-object\: Subject (e.g. account) has an attribute that contains identifier of the object (e.g. group).
Expand Down
Expand Up @@ -179,7 +179,7 @@ public void access(char[] chars) {
}

/**
* Disposes of the {@link CSVFileConnector}'s resources.
* Disposes of the connector's resources.
*
* @see Connector#dispose()
*/
Expand Down Expand Up @@ -1808,23 +1808,25 @@ private Date getDate(Attribute attr) {


private void changePassword(final DummyAccount account, Attribute attr) throws ConnectException, FileNotFoundException, SchemaViolationException {
if (attr.getValue() == null || attr.getValue().isEmpty()) {
throw new IllegalArgumentException("Empty password was provided");
}
Object passwdObject = attr.getValue().get(0);
if (!(passwdObject instanceof GuardedString)) {
throw new IllegalArgumentException("Password was provided as "+passwdObject.getClass().getName()+" while expecting GuardedString");
}
final String[] passwdArray = { "" };
((GuardedString)passwdObject).access(new Accessor() {
@Override
public void access(char[] passwdChars) {
if (configuration.getMinPasswordLength() != null && passwdChars.length < configuration.getMinPasswordLength()) {
throw new InvalidAttributeValueException("Password too short");
}
passwdArray[0] = new String(passwdChars);
final String[] passwdArray = { null };
if (attr.getValue() != null && !attr.getValue().isEmpty()) {
Object passwdObject = attr.getValue().get(0);
if (!(passwdObject instanceof GuardedString)) {
throw new IllegalArgumentException(
"Password was provided as " + passwdObject.getClass().getName() + " while expecting GuardedString");
}
});
((GuardedString)passwdObject).access(new Accessor() {
@Override
public void access(char[] passwdChars) {
if (configuration.getMinPasswordLength() != null && passwdChars.length < configuration.getMinPasswordLength()) {
throw new InvalidAttributeValueException("Password too short");
}
passwdArray[0] = new String(passwdChars);
}
});
} else {
// empty password => null
}
account.setPassword(passwdArray[0]);
}

Expand Down
Expand Up @@ -33,6 +33,7 @@
import com.evolveum.midpoint.util.PrettyPrinter;
import com.evolveum.midpoint.util.exception.SchemaException;
import com.evolveum.prism.xml.ns._public.types_3.PolyStringType;
import com.evolveum.prism.xml.ns._public.types_3.ProtectedStringType;
import com.evolveum.prism.xml.ns._public.types_3.RawType;
import com.evolveum.prism.xml.ns._public.types_3.SchemaDefinitionType;

Expand Down Expand Up @@ -277,6 +278,11 @@ public void checkConsistenceInternal(Itemable rootItem, boolean requireDefinitio
if (value instanceof PolyStringType) {
throw new IllegalStateException("PolyStringType found in property value "+this+" ("+myPath+" in "+rootItem+")");
}
if (value instanceof ProtectedStringType) {
if (((ProtectedStringType)value).isEmpty()) {
throw new IllegalStateException("Empty ProtectedStringType found in property value "+this+" ("+myPath+" in "+rootItem+")");
}
}
PrismContext prismContext = getPrismContext();
if (value instanceof PolyString && prismContext != null) {
PolyString poly = (PolyString)value;
Expand Down
Expand Up @@ -986,7 +986,7 @@ private <F extends ObjectType> void finishLoadOfProjectionContext(LensContext<F>
projContext.setExists(true);
GetOperationOptions rootOptions = new GetOperationOptions();
if (projContext.isDoReconciliation()) {
if (SchemaConstants.CHANGE_CHANNEL_DISCOVERY.equals(context.getChannel())) {
if (SchemaConstants.CHANGE_CHANNEL_DISCOVERY_URI.equals(context.getChannel())) {
// Avoid discovery loops
rootOptions.setDoNotDiscovery(true);
}
Expand Down
Expand Up @@ -16,7 +16,7 @@
package com.evolveum.midpoint.model.impl.lens.projector;

import java.util.Collection;
import java.util.List;
import java.util.Collections;

import javax.xml.datatype.XMLGregorianCalendar;
import javax.xml.namespace.QName;
Expand Down Expand Up @@ -227,14 +227,27 @@ public StringPolicyType resolve() {
passwordMapping.setStringPolicyResolver(stringPolicyResolver);

mappingEvaluator.evaluateMapping(passwordMapping, context, task, result);

PrismProperty<ProtectedStringType> accountPasswordNew = (PrismProperty) passwordMapping.getOutput();
if (accountPasswordNew == null || accountPasswordNew.isEmpty()) {
LOGGER.trace("Credentials 'password' expression resulted in null, skipping credentials processing for {}", rat);
return;
}
PropertyDelta<ProtectedStringType> accountPasswordDeltaNew = new PropertyDelta<ProtectedStringType>(SchemaConstants.PATH_PASSWORD_VALUE, accountPasswordPropertyDefinition, prismContext);
accountPasswordDeltaNew.setValuesToReplace(accountPasswordNew.getClonedValues());

// TODO review all this code !! MID-3156
// Originally here was "do nothing if output is null or empty".
// But because of MID-3111 we have to be a bit more cautious
PrismProperty<ProtectedStringType> accountPasswordNew = (PrismProperty) passwordMapping.getOutput();
if (accountPasswordNew == null || accountPasswordNew.isEmpty()) {
if (passwordMapping.getOutputTriple() == null) {
LOGGER.trace("Credentials 'password' expression resulted in null output triple, skipping credentials processing for {}", rat);
return;
}
if (passwordMapping.getStrength() != MappingStrengthType.STRONG) {
LOGGER.trace("Credentials 'password' expression resulted in 'no value' via non-strong mapping, skipping credentials processing for {}", rat);
return;
}
}
PropertyDelta<ProtectedStringType> accountPasswordDeltaNew = new PropertyDelta<>(SchemaConstants.PATH_PASSWORD_VALUE, accountPasswordPropertyDefinition, prismContext);
if (accountPasswordNew != null) {
accountPasswordDeltaNew.setValuesToReplace(accountPasswordNew.getClonedValues());
} else {
accountPasswordDeltaNew.setValuesToReplace(Collections.<PrismPropertyValue<ProtectedStringType>>emptyList());
}
LOGGER.trace("Adding new password delta for account {}", rat);
accCtx.swallowToSecondaryDelta(accountPasswordDeltaNew);

Expand Down
Expand Up @@ -352,6 +352,10 @@ <F extends ObjectType> void processPasswordPolicy(LensProjectionContext projecti

private <F extends ObjectType> boolean isCheckOrgPolicy(LensContext<F> context) throws SchemaException{
LensFocusContext focusCtx = context.getFocusContext();
if (focusCtx == null) {
return false; // TODO - ok?
}

if (focusCtx.getDelta() != null){
if (focusCtx.getDelta().isAdd()){
return false;
Expand Down
Expand Up @@ -16,10 +16,7 @@
package com.evolveum.midpoint.model.intest;

import static com.evolveum.midpoint.test.IntegrationTestTools.display;
import static org.testng.AssertJUnit.assertEquals;
import static org.testng.AssertJUnit.assertNotNull;
import static org.testng.AssertJUnit.assertTrue;
import static org.testng.AssertJUnit.assertFalse;
import static org.testng.AssertJUnit.*;

import java.io.File;
import java.util.ArrayList;
Expand Down Expand Up @@ -750,6 +747,47 @@ public void test300TwoParentOrgRefs() throws Exception {
assertDummyPassword(RESOURCE_DUMMY_RED_NAME, ACCOUNT_JACK_DUMMY_USERNAME, USER_PASSWORD_VALID);
}

/*
* Remove password. It should be removed from red resource as well. (MID-3111)
* Also unassign yellow resource (requires non-empty password), all orgs, and remove default password policy.
*/
@Test
public void test310RemovePassword() throws Exception {
final String TEST_NAME = "test310RemovePassword";
TestUtil.displayTestTile(this, TEST_NAME);

// GIVEN
Task task = taskManager.createTaskInstance(TestPassword.class.getName() + "." + TEST_NAME);
OperationResult result = task.getResult();
assumeAssignmentPolicy(AssignmentPolicyEnforcementType.FULL);

unassignAccount(USER_JACK_OID, RESOURCE_DUMMY_YELLOW_OID, null, task, result);
unassignOrg(USER_JACK_OID, ORG_GOVERNOR_OFFICE_OID, null, task, result);
unassignOrg(USER_JACK_OID, ORG_GOVERNOR_OFFICE_OID, SchemaConstants.ORG_MANAGER, task, result);
modifyObjectReplaceReference(SystemConfigurationType.class, SystemObjectsType.SYSTEM_CONFIGURATION.value(),
SystemConfigurationType.F_GLOBAL_PASSWORD_POLICY_REF, task, result);

// WHEN
modifyUserReplace(USER_JACK_OID, PASSWORD_VALUE_PATH, task, result);

// THEN
result.computeStatus();
TestUtil.assertSuccess(result);

PrismObject<UserType> userJack = getUser(USER_JACK_OID);
display("User after change execution", userJack);
assertUserJack(userJack, "Jack Sparrow");

assertNull("User password is not null", userJack.asObjectable().getCredentials().getPassword().getValue());
assertDummyPassword(ACCOUNT_JACK_DUMMY_USERNAME, USER_PASSWORD_VALID); // password mapping is weak here - so no change is expected

assertNoDummyAccount(RESOURCE_DUMMY_YELLOW_NAME, ACCOUNT_JACK_DUMMY_USERNAME);

assertDummyAccount(RESOURCE_DUMMY_RED_NAME, ACCOUNT_JACK_DUMMY_USERNAME, ACCOUNT_JACK_DUMMY_FULLNAME, true);
assertDummyPassword(RESOURCE_DUMMY_RED_NAME, ACCOUNT_JACK_DUMMY_USERNAME, null); // password mapping is strong here
}


private void assertDummyPassword(String userId, String expectedClearPassword) throws SchemaViolationException {
assertDummyPassword(null, userId, expectedClearPassword);
}
Expand Down
Expand Up @@ -19,13 +19,7 @@

import java.io.File;
import java.lang.reflect.Array;
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 javax.xml.datatype.XMLGregorianCalendar;
import javax.xml.namespace.QName;
Expand Down Expand Up @@ -2728,12 +2722,12 @@ private void convertFromPassword(Set<Attribute> attributes, PropertyDelta<Protec
}
PrismProperty<ProtectedStringType> newPassword = passwordDelta.getPropertyNewMatchingPath();
if (newPassword == null || newPassword.isEmpty()) {
LOGGER.trace("Skipping processing password delta. Password delta does not contain new value.");
return;
LOGGER.debug("Setting null password.");
attributes.add(AttributeBuilder.build(OperationalAttributes.PASSWORD_NAME, Collections.EMPTY_LIST));
} else {
GuardedString guardedPassword = IcfUtil.toGuardedString(newPassword.getValue().getValue(), "new password", protector);
attributes.add(AttributeBuilder.build(OperationalAttributes.PASSWORD_NAME, guardedPassword));
}
GuardedString guardedPassword = IcfUtil.toGuardedString(newPassword.getValue().getValue(), "new password", protector);
attributes.add(AttributeBuilder.build(OperationalAttributes.PASSWORD_NAME, guardedPassword));

}

private void addConvertedValues(Collection<PrismPropertyValue<QName>> pvals,
Expand Down
1 change: 1 addition & 0 deletions repo/repo-sql-impl-test/pom.xml
Expand Up @@ -106,6 +106,7 @@
<dependency>
<groupId>org.jetbrains</groupId>
<artifactId>annotations-java5</artifactId>
<scope>test</scope>
</dependency>

<dependency>
Expand Down
4 changes: 4 additions & 0 deletions samples/evolveum/resource-openldap.xml
Expand Up @@ -69,6 +69,7 @@
<icfcldap:operationalAttributes>memberOf</icfcldap:operationalAttributes>
<icfcldap:operationalAttributes>createTimestamp</icfcldap:operationalAttributes>
<icfcldap:usePermissiveModify>always</icfcldap:usePermissiveModify>
<icfcldap:lockoutStrategy>openldap</icfcldap:lockoutStrategy>
</icfc:configurationProperties>
<icfc:resultsHandlerConfiguration>
<icfc:enableNormalizingResultsHandler>false</icfc:enableNormalizingResultsHandler>
Expand Down Expand Up @@ -288,6 +289,9 @@
</expression>
</inbound>
</administrativeStatus>
<lockoutStatus>
<outbound/>
</lockoutStatus>
</activation>

<credentials>
Expand Down
Expand Up @@ -896,7 +896,7 @@ public void test150GetConfigNoPasswordWrongDigest() throws Exception {
displayTestTitle(TEST_NAME);

LogfileTestTailer tailer = createLogTailer();
modelPort = createModelPort(USER_NOBODY_USERNAME, "wrongPassword", WSConstants.PW_DIGEST);
modelPort = createModelPort(USER_NOPASSWORD_USERNAME, "wrongPassword", WSConstants.PW_DIGEST);

Holder<ObjectType> objectHolder = new Holder<ObjectType>();
Holder<OperationResultType> resultHolder = new Holder<OperationResultType>();
Expand All @@ -913,7 +913,7 @@ public void test150GetConfigNoPasswordWrongDigest() throws Exception {
}

tailer.tail();
assertAuditLoginFailed(tailer, "no authorizations");
assertAuditLoginFailed(tailer, "no credentials in user");
}

@Test
Expand All @@ -922,7 +922,7 @@ public void test152GetConfigNoPasswordEmptyDigest() throws Exception {
displayTestTitle(TEST_NAME);

LogfileTestTailer tailer = createLogTailer();
modelPort = createModelPort(USER_NOBODY_USERNAME, " ", WSConstants.PW_DIGEST);
modelPort = createModelPort(USER_NOPASSWORD_USERNAME, " ", WSConstants.PW_DIGEST);

Holder<ObjectType> objectHolder = new Holder<ObjectType>();
Holder<OperationResultType> resultHolder = new Holder<OperationResultType>();
Expand All @@ -939,7 +939,7 @@ public void test152GetConfigNoPasswordEmptyDigest() throws Exception {
}

tailer.tail();
assertAuditLoginFailed(tailer, "no authorizations");
assertAuditLoginFailed(tailer, "no credentials in user");
}

@Test
Expand Down

0 comments on commit 9a9dd2f

Please sign in to comment.