Skip to content

Commit

Permalink
implementing MID-4602 and MID-4603 (cherry picked
Browse files Browse the repository at this point in the history
  • Loading branch information
katkav committed Jun 5, 2018
1 parent bda5a5d commit 88ec992
Show file tree
Hide file tree
Showing 8 changed files with 160 additions and 9 deletions.
Expand Up @@ -133,6 +133,10 @@ public SecurityPolicyType getSecurityPolicy() {
public void setSecurityPolicy(SecurityPolicyType securityPolicy) {
this.securityPolicy = securityPolicy;
}

public void setValuePolicy(ValuePolicyType valuePolicy) {
this.valuePolicy = valuePolicy;
}

public XMLGregorianCalendar getNow() {
return now;
Expand Down Expand Up @@ -236,6 +240,9 @@ private void prepare() throws SchemaException {
}

private void prepareValuePolicy() {
if (valuePolicy != null) {
return;
}
if (credentialPolicy != null) {
ObjectReferenceType valuePolicyRef = credentialPolicy.getValuePolicyRef();
if (valuePolicyRef != null) {
Expand All @@ -249,6 +256,11 @@ private void prepareValuePolicy() {
}

private void preparePassword() {

if (valueItemPath == null) {
return;
}

if (!QNameUtil.match(UserType.F_CREDENTIALS, valueItemPath.getFirstName())) {
return;
}
Expand All @@ -260,14 +272,22 @@ private void preparePassword() {
if (!QNameUtil.match(CredentialsType.F_PASSWORD, credentialQName)) {
return;
}


if (securityPolicy == null) {
return;
}

credentialPolicy = SecurityUtil.getEffectivePasswordCredentialsPolicy(securityPolicy);
}

private void prepareNonce() throws SchemaException {
if (!QNameUtil.match(CredentialsType.F_NONCE, credentialQName)) {
return;
}

if (securityPolicy == null) {
return;
}

credentialPolicy = SecurityUtil.getEffectiveNonceCredentialsPolicy(securityPolicy);
}
Expand Down
Expand Up @@ -63,6 +63,7 @@
import com.evolveum.midpoint.model.common.SystemObjectCache;
import com.evolveum.midpoint.model.common.mapping.MappingFactory;
import com.evolveum.midpoint.model.common.stringpolicy.AbstractValuePolicyOriginResolver;
import com.evolveum.midpoint.model.common.stringpolicy.ObjectValuePolicyEvaluator;
import com.evolveum.midpoint.model.common.stringpolicy.ShadowValuePolicyOriginResolver;
import com.evolveum.midpoint.model.common.stringpolicy.StringPolicyUtils;
import com.evolveum.midpoint.model.common.stringpolicy.UserValuePolicyOriginResolver;
Expand All @@ -74,8 +75,11 @@
import com.evolveum.midpoint.model.impl.lens.LensContext;
import com.evolveum.midpoint.model.impl.lens.LensContextPlaceholder;
import com.evolveum.midpoint.model.impl.lens.LensUtil;
import com.evolveum.midpoint.model.impl.lens.OperationalDataManager;
import com.evolveum.midpoint.model.impl.lens.projector.MappingEvaluator;
import com.evolveum.midpoint.model.impl.lens.projector.Projector;
import com.evolveum.midpoint.model.impl.lens.projector.credentials.CredentialsProcessor;
import com.evolveum.midpoint.model.impl.lens.projector.credentials.PasswordPolicyEvaluator;
import com.evolveum.midpoint.model.impl.security.SecurityHelper;
import com.evolveum.midpoint.model.impl.visualizer.Visualizer;
import com.evolveum.midpoint.prism.ComplexTypeDefinitionImpl;
Expand Down Expand Up @@ -193,6 +197,7 @@
import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectTemplateType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.OtherPrivilegesLimitationType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.PasswordType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.RegistrationsPolicyType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.ResourceType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.RoleType;
Expand Down Expand Up @@ -243,6 +248,7 @@ public class ModelInteractionServiceImpl implements ModelInteractionService {
@Autowired UserProfileService userProfileService;
@Autowired private ExpressionFactory expressionFactory;
@Autowired private CacheRegistry cacheRegistry;
@Autowired private OperationalDataManager metadataManager;

private static final String OPERATION_GENERATE_VALUE = ModelInteractionService.class.getName() + ".generateValue";
private static final String OPERATION_VALIDATE_VALUE = ModelInteractionService.class.getName() + ".validateValue";
Expand Down Expand Up @@ -1313,17 +1319,49 @@ private <T, O extends ObjectType> boolean validateValue(PrismObject<O> object, V

for (String newValue : valuesToValidate) {
OperationResult result = parentResult.createSubresult(OPERATION_VALIDATE_VALUE + ".value");
if (path != null ) result.addArbitraryObjectAsParam("path", path);
if (path != null ) result.addParam("path", path.toString());
result.addParam("valueToValidate", newValue);
if (stringPolicy == null) {
stringPolicy = new ValuePolicyType();
stringPolicy.setName(PolyString.toPolyStringType(new PolyString("Default policy")));
}
if (!policyProcessor.validateValue(newValue, stringPolicy, createOriginResolver(object, result), "validate value " + (path!= null ? "for " + path : "") + " for " + object + " value " + valueToValidate, task, result)) {
result.recordFatalError("Validation for value " + newValue + " against policy " + stringPolicy + " failed");
LOGGER.error("Validation for value {} against policy {} failed", newValue, stringPolicy);

ObjectValuePolicyEvaluator evaluator = new ObjectValuePolicyEvaluator();
evaluator.setValuePolicy(stringPolicy);
evaluator.setValuePolicyProcessor(policyProcessor);
evaluator.setProtector(protector);
evaluator.setValueItemPath(path);
evaluator.setOriginResolver(getOriginResolver(object));
evaluator.setTask(task);
evaluator.setShortDesc(" rest validate ");
if (object != null && path != null && SchemaConstants.PATH_PASSWORD.isSuperPathOrEquivalent(path)) {
evaluator.setSecurityPolicy(getSecurityPolicy((PrismObject<UserType>) object, task, parentResult));
PrismContainer<PasswordType> password = object.findContainer(SchemaConstants.PATH_PASSWORD);
PasswordType passwordType = null;
if (password != null) {
PrismContainerValue<PasswordType> passwordPcv = password.getValue();
passwordType = passwordPcv != null ? passwordPcv.asContainerable() : null;
}
evaluator.setOldCredentialType(passwordType);
}
result.computeStatusIfUnknown();
evaluator.setNow(clock.currentTimeXMLGregorianCalendar());
try {
LOGGER.trace("Validating value started");
OperationResult subResult = evaluator.validateStringValue(newValue);
LOGGER.trace("Validating value finished");
result.addSubresult(subResult);
// result.recomputeStatus();
} catch(Exception e) {
result.recordFatalError("Cannot validate value. " + e.getMessage());
}

result.computeStatus();

// if (!policyProcessor.validateValue(newValue, stringPolicy, createOriginResolver(object, result), "validate value " + (path!= null ? "for " + path : "") + " for " + object + " value " + valueToValidate, task, result)) {
// result.recordFatalError("Validation for value " + newValue + " against policy " + stringPolicy + " failed");
// LOGGER.error("Validation for value {} against policy {} failed", newValue, stringPolicy);
// }

}

parentResult.computeStatus();
Expand All @@ -1333,6 +1371,15 @@ private <T, O extends ObjectType> boolean validateValue(PrismObject<O> object, V

}

private <O extends ObjectType> AbstractValuePolicyOriginResolver<O> getOriginResolver(PrismObject<O> object) {
if (object != null && UserType.class.equals(object.getCompileTimeClass())) {
new UserValuePolicyOriginResolver((PrismObject<UserType>) object, objectResolver);
}

//TODO not supported yet
return null;
}

private <O extends ObjectType> AbstractValuePolicyOriginResolver<O> createOriginResolver(PrismObject<O> object, OperationResult result) throws SchemaException {
if (object == null) {
return null;
Expand Down
Expand Up @@ -91,6 +91,7 @@ public abstract class TestAbstractRestService extends RestServiceInitializer {
public static final String POLICY_ITEM_DEFINITION_VALIDATE_EXPLICIT_CONFLICT = "policy-validate-explicit-conflict";
public static final String POLICY_ITEM_DEFINITION_VALIDATE_IMPLICIT_SINGLE = "policy-validate-implicit-single";
public static final String POLICY_ITEM_DEFINITION_VALIDATE_IMPLICIT_PASSWORD = "policy-validate-implicit-password";
public static final String POLICY_ITEM_DEFINITION_VALIDATE_PASSWORD_PASSWORD_HISTORY_CONFLICT = "policy-validate-password-history-conflict";
public static final String POLICY_ITEM_DEFINITION_VALIDATE_IMPLICIT_MULTI = "policy-validate-implicit-multi";
public static final String POLICY_ITEM_DEFINITION_VALIDATE_IMPLICIT_MULTI_CONFLICT = "policy-validate-implicit-multi-conflict";

Expand Down Expand Up @@ -957,12 +958,26 @@ public void test506generateHonorificPrefixNameExecute() throws Exception {
//TODO assert changed items
}

private OperationResult traceResponse(Response response) throws SchemaException {
private OperationResult traceResponse(Response response) { //throws SchemaException {
if (response.getStatus() != 200 && response.getStatus() != 201 && response.getStatus() != 204) {
LOGGER.info("coverting result");
OperationResultType result = response.readEntity(OperationResultType.class);
<<<<<<< HEAD
LOGGER.info("####RESULT");
OperationResult opResult = OperationResult.createOperationResult(result);
LOGGER.info(opResult.debugDump());
=======
LOGGER.info("tracing result");
OperationResult opResult = null;
try {
opResult = OperationResult.createOperationResult(result);
} catch (Exception e) {
LOGGER.info("Failed to create operation result. Reason: " + e.getMessage(), e);
return null;
}
LOGGER.info("REST resutl {}", opResult.debugDump());
display("REST result", opResult);
>>>>>>> 9aeb9b6f9d... implementing MID-4603 and MID-4602
return opResult;
}

Expand Down Expand Up @@ -1111,6 +1126,31 @@ public void test515validateValueImplicitPassword() throws Exception {
assertEquals("Expected 200 but got " + response.getStatus(), 200, response.getStatus());


display("Audit", getDummyAuditService());
getDummyAuditService().assertRecords(2);
getDummyAuditService().assertLoginLogout(SchemaConstants.CHANNEL_REST_URI);
}

@Test
public void test516validatePasswordHistoryConflict() throws Exception {
final String TEST_NAME = "test516validatePasswordHistoryConflict";
displayTestTitle(this, TEST_NAME);

WebClient client = prepareClient();
client.path("/users/" + USER_DARTHADDER_OID + "/validate");

getDummyAuditService().clear();

TestUtil.displayWhen(TEST_NAME);
Response response = client.post(getRepoFile(POLICY_ITEM_DEFINITION_VALIDATE_IMPLICIT_PASSWORD));

TestUtil.displayThen(TEST_NAME);
displayResponse(response);


assertEquals("Expected 200 but got " + response.getStatus(), 200, response.getStatus());


display("Audit", getDummyAuditService());
getDummyAuditService().assertRecords(2);
getDummyAuditService().assertLoginLogout(SchemaConstants.CHANNEL_REST_URI);
Expand Down
5 changes: 3 additions & 2 deletions testing/rest/src/test/resources/logback-test.xml
Expand Up @@ -30,15 +30,16 @@
<logger name="org.springframework" level="WARN" />
<logger name="com.evolveum.midpoint" level="DEBUG" />
<logger name="com.evolveum.midpoint.provisioning" level="TRACE" />
<logger name="com.evolveum.midpoint.model" level="DEBUG" />
<logger name="com.evolveum.midpoint.model" level="TRACE" />
<logger name="com.evolveum.midpoint.model.impl.security.MidpointRestAuthenticationHandler" level="TRACE" />
<logger name="org.apache.cxf" level="FINE" />
<!--<logger name="com.evolveum.midpoint.provisioning" level="TRACE" />-->
<!--<logger name="com.evolveum.midpoint.common" level="TRACE" />-->
<!-- <logger name="com.evolveum.midpoint.common" level="TRACE" /> -->

<!-- Silencing some chatty packages -->
<logger name="com.evolveum.midpoint.model.repo.sql.query" level="DEBUG" />
<logger name="com.evolveum.midpoint.repo" level="DEBUG" />
<logger name="com.evolveum.midpoint.schema" level="TRACE" />
<logger name="org.hibernate.engine.jdbc.spi.SqlExceptionHelper" level="OFF"/>
<logger name="com.evolveum.midpoint.model.sync.action" level="DEBUG" />

Expand Down
@@ -0,0 +1,17 @@
{
"@ns": "http://midpoint.evolveum.com/xml/ns/public/common/api-types-3",
"policyItemsDefinition": {
"policyItemDefinition": [
{
"target": {
"path": "credentials/password/value"
},
"valuePolicyRef": {
"type": "http://midpoint.evolveum.com/xml/ns/public/common/common-3#ValuePolicyType",
"oid": "81818181-76e0-0000-8888-3d4f02d3fffb"
},
"value": "iamyouruncle"
}
]
}
}
1 change: 1 addition & 0 deletions testing/rest/src/test/resources/repo/security-policy.xml
Expand Up @@ -24,6 +24,7 @@
<lockoutMaxFailedAttempts>3</lockoutMaxFailedAttempts>
<lockoutFailedAttemptsDuration>PT3M</lockoutFailedAttemptsDuration>
<lockoutDuration>PT15M</lockoutDuration>
<passwordHistoryLength>3</passwordHistoryLength>
</password>
<nonce>
<maxAge>P30D</maxAge>
Expand Down
@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<policyItemsDefinition xmlns="http://midpoint.evolveum.com/xml/ns/public/common/api-types-3"
xmlns:q="http://prism.evolveum.com/xml/ns/public/query-3"
xmlns:c="http://midpoint.evolveum.com/xml/ns/public/common/common-3"
xmlns:t="http://prism.evolveum.com/xml/ns/public/types-3"
xmlns:icfs="http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/resource-schema-3"
xmlns:ri="http://midpoint.evolveum.com/xml/ns/public/resource/instance-3">
<policyItemDefinition>
<target>
<path>credentials/password/value</path>
</target>
<valuePolicyRef oid="81818181-76e0-0000-8888-3d4f02d3fffb" type="c:ValuePolicyType"/>
<value>iamyouruncle</value>
</policyItemDefinition>

</policyItemsDefinition>
@@ -0,0 +1,9 @@
'@ns': "http://midpoint.evolveum.com/xml/ns/public/common/api-types-3"
policyItemsDefinition:
policyItemDefinition:
- target:
path: "credentials/password/value"
valuePolicyRef:
type: "http://midpoint.evolveum.com/xml/ns/public/common/common-3#ValuePolicyType"
oid: "81818181-76e0-0000-8888-3d4f02d3fffb"
value: "iamyouruncle"

0 comments on commit 88ec992

Please sign in to comment.