Skip to content

Commit

Permalink
Merge remote-tracking branch 'refs/remotes/origin/master'
Browse files Browse the repository at this point in the history
  • Loading branch information
skublik committed Mar 1, 2019
2 parents 0ddbf58 + 7e885c1 commit a682c34
Show file tree
Hide file tree
Showing 18 changed files with 334 additions and 40 deletions.
Expand Up @@ -1132,22 +1132,28 @@ private <O extends ObjectType> ValuePolicyType getValuePolicy(PrismObject<O> obj
CredentialsPolicyType policy = null;
PrismObject<UserType> user = null;
if (object != null && object.getCompileTimeClass().isAssignableFrom(UserType.class)) {
LOGGER.trace("Start to resolve policy for user");
user = (PrismObject<UserType>) object;
policy = getCredentialsPolicy(user, task, parentResult);
LOGGER.trace("Resolved user policy: {}", policy);
}



SystemConfigurationType systemConfigurationType = getSystemConfiguration(parentResult);
if (!containsValuePolicyDefinition(policy)) {
SecurityPolicyType securityPolicy = securityHelper.locateGlobalSecurityPolicy(user, systemConfigurationType.asPrismObject(), task, parentResult);
if (securityPolicy != null) {
policy = securityPolicy.getCredentials();
LOGGER.trace("Resolved policy from global security policy: {}", policy);
}
}

if (!containsValuePolicyDefinition(policy)) {
SecurityPolicyType securityPolicy = securityHelper.locateGlobalPasswordPolicy(systemConfigurationType, task, parentResult);
if (securityPolicy != null) {
policy = securityPolicy.getCredentials();
LOGGER.trace("Resolved global password policy: {}", policy);
}
}

Expand Down Expand Up @@ -1278,15 +1284,34 @@ private <T, O extends ObjectType> boolean validateValue(PrismObject<O> object, V
evaluator.setOriginResolver(getOriginResolver(object));
evaluator.setTask(task);
evaluator.setShortDesc(" rest validate ");
if (object != null && path != null && path.isSuperPathOrEquivalent(SchemaConstants.PATH_PASSWORD)) {
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;
if (object != null && path != null) {
if (path.isSuperPathOrEquivalent(SchemaConstants.PATH_PASSWORD)) {

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);
} else if (path.isSuperPathOrEquivalent(SchemaConstants.PATH_SECURITY_QUESTIONS)) {
LOGGER.trace("Setting security questions related policy.");
SecurityPolicyType securityPolicy = getSecurityPolicy((PrismObject<UserType>) object, task, parentResult);
evaluator.setSecurityPolicy(securityPolicy);
PrismContainer<SecurityQuestionsCredentialsType> securityQuestionsContainer = object.findContainer(SchemaConstants.PATH_SECURITY_QUESTIONS);
SecurityQuestionsCredentialsType securityQuestions = null;
if (securityQuestionsContainer != null) {
PrismContainerValue<SecurityQuestionsCredentialsType> secQestionPcv = securityQuestionsContainer.getValue();
securityQuestions = secQestionPcv != null ? secQestionPcv.asContainerable() : null;
}
//evaluator.setOldCredentialType(securityQuestions);

ValuePolicyType valuePolicy = resolveSecurityQuestionsPolicy(securityPolicy, task, parentResult);
if (valuePolicy != null) {
evaluator.setValuePolicy(valuePolicy);
}
}
evaluator.setOldCredentialType(passwordType);
}
evaluator.setNow(clock.currentTimeXMLGregorianCalendar());
LOGGER.trace("Validating value started");
Expand All @@ -1310,6 +1335,39 @@ private <T, O extends ObjectType> boolean validateValue(PrismObject<O> object, V

}

/**
* @param securityPolicy
* @return
* @throws ExpressionEvaluationException
* @throws SecurityViolationException
* @throws ConfigurationException
* @throws CommunicationException
* @throws SchemaException
* @throws ObjectNotFoundException
*/
private ValuePolicyType resolveSecurityQuestionsPolicy(SecurityPolicyType securityPolicy, Task task, OperationResult result) throws ObjectNotFoundException, SchemaException, CommunicationException, ConfigurationException, SecurityViolationException, ExpressionEvaluationException {
if (securityPolicy == null) {
return null;
}

CredentialsPolicyType credentialsPolicy = securityPolicy.getCredentials();
if (credentialsPolicy == null) {
return null;
}

SecurityQuestionsCredentialsPolicyType securityQuestionsPolicy = credentialsPolicy.getSecurityQuestions();
if (securityQuestionsPolicy == null) {
return null;
}

ObjectReferenceType policyRef = securityQuestionsPolicy.getValuePolicyRef();
if (policyRef == null) {
return null;
}

return objectResolver.resolve(policyRef, ValuePolicyType.class, null, " resolve value policy for security questions", task, result);
}

private <O extends ObjectType> AbstractValuePolicyOriginResolver<O> getOriginResolver(PrismObject<O> object) {
if (object != null && UserType.class.equals(object.getCompileTimeClass())) {
return (AbstractValuePolicyOriginResolver) new UserValuePolicyOriginResolver((PrismObject<UserType>) object, objectResolver);
Expand Down
4 changes: 4 additions & 0 deletions testing/rest/pom.xml
Expand Up @@ -110,6 +110,10 @@
<artifactId>repo-test-util</artifactId>
<version>4.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
</dependency>

<dependency>
<groupId>commons-lang</groupId>
Expand Down
Expand Up @@ -105,6 +105,7 @@ public abstract class RestServiceInitializer {
public static final File VALUE_POLICY_GENERAL = new File(BASE_REPO_DIR, "value-policy-general.xml");
public static final File VALUE_POLICY_NUMERIC = new File(BASE_REPO_DIR, "value-policy-numeric.xml");
public static final File VALUE_POLICY_SIMPLE = new File(BASE_REPO_DIR, "value-policy-simple.xml");
public static final File VALUE_POLICY_SECURITY_ANSWER = new File(BASE_REPO_DIR, "value-policy-security-answer.xml");
public static final File SECURITY_POLICY = new File(BASE_REPO_DIR, "security-policy.xml");
public static final File SECURITY_POLICY_NO_HISTORY = new File(BASE_REPO_DIR, "security-policy-no-history.xml");

Expand Down Expand Up @@ -177,6 +178,7 @@ public void startServer() throws Exception {
addObject(VALUE_POLICY_GENERAL, result);
addObject(VALUE_POLICY_NUMERIC, result);
addObject(VALUE_POLICY_SIMPLE, result);
addObject(VALUE_POLICY_SECURITY_ANSWER, result);
addObject(SECURITY_POLICY, result);
addObject(SYSTEM_CONFIGURATION_FILE, result);

Expand Down
Expand Up @@ -17,8 +17,8 @@

import static com.evolveum.midpoint.test.IntegrationTestTools.display;
import static com.evolveum.midpoint.test.util.TestUtil.displayTestTitle;
import static com.evolveum.midpoint.test.util.TestUtil.displayWhen;
import static com.evolveum.midpoint.test.util.TestUtil.displayThen;
import static com.evolveum.midpoint.test.util.TestUtil.displayWhen;
import static org.testng.AssertJUnit.assertEquals;
import static org.testng.AssertJUnit.assertNotNull;
import static org.testng.AssertJUnit.assertTrue;
Expand All @@ -34,36 +34,53 @@
import javax.xml.datatype.XMLGregorianCalendar;
import javax.xml.namespace.QName;

import com.evolveum.midpoint.prism.Referencable;
import com.evolveum.midpoint.prism.crypto.EncryptionException;
import com.evolveum.midpoint.prism.polystring.PolyString;
import com.evolveum.midpoint.prism.xml.XmlTypeConverter;
import com.evolveum.midpoint.repo.api.RepoAddOptions;
import com.evolveum.midpoint.util.exception.*;

import com.evolveum.midpoint.xml.ns._public.common.api_types_3.ExecuteScriptResponseType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.*;
import com.evolveum.midpoint.xml.ns._public.model.scripting_3.PipelineItemType;
import com.evolveum.prism.xml.ns._public.types_3.RawType;
import org.apache.commons.lang.BooleanUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.cxf.jaxrs.client.WebClient;
import org.testng.AssertJUnit;
import org.testng.annotations.Test;

import com.evolveum.midpoint.prism.PrismObject;
import com.evolveum.midpoint.prism.Referencable;
import com.evolveum.midpoint.prism.crypto.EncryptionException;
import com.evolveum.midpoint.prism.delta.ChangeType;
import com.evolveum.midpoint.prism.polystring.PolyString;
import com.evolveum.midpoint.prism.xml.XmlTypeConverter;
import com.evolveum.midpoint.repo.api.RepoAddOptions;
import com.evolveum.midpoint.schema.GetOperationOptions;
import com.evolveum.midpoint.schema.SelectorOptions;
import com.evolveum.midpoint.schema.constants.SchemaConstants;
import com.evolveum.midpoint.schema.result.OperationResult;
import com.evolveum.midpoint.schema.result.OperationResultStatus;
import com.evolveum.midpoint.util.MiscUtil;
import com.evolveum.midpoint.util.QNameUtil;
import com.evolveum.midpoint.util.exception.ObjectNotFoundException;
import com.evolveum.midpoint.util.exception.SchemaException;
import com.evolveum.midpoint.util.logging.Trace;
import com.evolveum.midpoint.util.logging.TraceManager;
import com.evolveum.midpoint.xml.ns._public.common.api_types_3.ExecuteScriptResponseType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.ActivationStatusType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.CredentialsType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.FunctionLibraryType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.LocalizableMessageListType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.LocalizableMessageType;
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.OperationResultStatusType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.OperationResultType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.PasswordType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.RoleType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.ScriptExpressionEvaluatorType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.SecurityQuestionAnswerType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.SecurityQuestionsCredentialsType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.SingleLocalizableMessageType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.SystemObjectsType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.UserType;
import com.evolveum.midpoint.xml.ns._public.model.scripting_3.PipelineItemType;
import com.evolveum.prism.xml.ns._public.query_3.QueryType;
import com.evolveum.prism.xml.ns._public.types_3.ProtectedStringType;
import com.evolveum.prism.xml.ns._public.types_3.RawType;


public abstract class TestAbstractRestService extends RestServiceInitializer {
Expand Down Expand Up @@ -101,6 +118,8 @@ public abstract class TestAbstractRestService extends RestServiceInitializer {
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";
public static final String POLICY_ITEM_DEFINITION_VALIDATE_SECURITY_ANSWER_CHECK_EXPRESSION_FAIL = "policy-validate-security-answer-check-expression-fail";
public static final String POLICY_ITEM_DEFINITION_VALIDATE_SECURITY_ANSWER_CHECK_EXPRESSION = "policy-validate-security-answer-check-expression";

public static final String SCRIPT_GENERATE_PASSWORDS = "script-generate-passwords";
public static final String SCRIPT_MODIFY_VALID_TO = "script-modify-validTo";
Expand Down Expand Up @@ -1303,7 +1322,7 @@ public void test518validateValueImplicitPassword() throws Exception {


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

addObject(SECURITY_POLICY, RepoAddOptions.createOverwrite(), result);

display("Audit", getDummyAuditService());
getDummyAuditService().assertRecords(2);
Expand All @@ -1330,12 +1349,9 @@ public void test520GeneratePasswordsUsingScripting() throws Exception {

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

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

ExecuteScriptResponseType responseData = response.readEntity(ExecuteScriptResponseType.class);
display("Response", getPrismContext().xmlSerializer().serializeRealValue(responseData));
LOGGER.info("Response: {}", getPrismContext().xmlSerializer().serializeRealValue(responseData));

List<PipelineItemType> items = responseData.getOutput().getDataOutput().getItem();
assertEquals("Wrong # of processed items", 2, items.size());
Expand All @@ -1352,13 +1368,20 @@ public void test520GeneratePasswordsUsingScripting() throws Exception {
ItemProcessingResult<PasswordGenerationData> second = extractedResults.get(1);
assertEquals("Wrong OID in second result", USER_JACK_OID, second.oid);
assertEquals("Wrong name in second result", "jack", second.name);
LOGGER.info("pwd in second result {}", second.data.password);
assertNotNull("Missing password in second result", second.data.password);

assertEquals("Wrong status in second result", OperationResultStatusType.SUCCESS, second.status);

UserType jackAfter = getRepositoryService()
.getObject(UserType.class, USER_JACK_OID, null, new OperationResult("getObject")).asObjectable();
display("jack after", jackAfter);
assertNotNull("password not set", jackAfter.getCredentials().getPassword().getValue());

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

}

@Test
Expand Down Expand Up @@ -1646,6 +1669,55 @@ public void test606ModifySecurityQuestionReplaceAnswer() throws Exception {
display("User after", userRepoAfter);
assertSecurityQuestionAnswer(userRepoAfter.asObjectable(), "you would not believe what happens next");
}

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

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

getDummyAuditService().clear();

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

displayThen(TEST_NAME);
displayResponse(response);
traceResponse(response);

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


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

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

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

getDummyAuditService().clear();

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

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

private void assertSecurityQuestionAnswer(UserType userType, String expectedAnswer) throws EncryptionException {
CredentialsType credentials = userType.getCredentials();
Expand Down
10 changes: 5 additions & 5 deletions testing/rest/src/test/resources/logback-test.xml
Expand Up @@ -16,13 +16,10 @@
-->

<configuration>


<appender name="X" class="ch.qos.logback.core.FileAppender">
<file>./target/test.log</file>
<encoder>
<!-- <pattern>%date [%thread] %-5level [%X{subsystem}]\(%logger{46}\): %message%n%caller{16}</pattern> -->
<pattern>%date [%thread] %-5level [%X{subsystem}]\(%logger{46}\): %message%n</pattern>
<pattern>%date [%thread] %-5level \(%logger{46}\): %message%n</pattern>
</encoder>
</appender>

Expand All @@ -32,6 +29,9 @@
<logger name="com.evolveum.midpoint.provisioning" level="TRACE" />
<logger name="com.evolveum.midpoint.model" level="TRACE" />
<logger name="com.evolveum.midpoint.model.impl.security.MidpointRestAuthenticationHandler" level="TRACE" />
<logger name="com.evolveum.midpoint.model.impl.controller" 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" /> -->
Expand All @@ -50,7 +50,7 @@
<logger name="com.evolveum.midpoint.testing.rest" level="TRACE" />
<logger name="com.evolveum.midpoint.test" level="TRACE" />
<logger name="PROFILING" level="TRACE" />
<root level="WARN">
<root level="INFO">
<appender-ref ref="X" />
</root>
</configuration>
Expand Down
Expand Up @@ -5,11 +5,6 @@
"target": {
"path": "credentials/password/value"
},
"valuePolicyRef": {
"@ns": "http://midpoint.evolveum.com/xml/ns/public/common/common-3",
"type": "http://midpoint.evolveum.com/xml/ns/public/common/common-3#ValuePolicyType",
"oid": "81818181-76e0-0000-8888-3d4f02d3fffb"
},
"execute" : "true"
}]
}
Expand Down
@@ -0,0 +1,13 @@
{
"@ns": "http://midpoint.evolveum.com/xml/ns/public/common/api-types-3",
"policyItemsDefinition": {
"policyItemDefinition": [
{
"target": {
"path": "credentials/securityQuestions/questionAnswer[1]/questionAnswer"
},
"value": "darthadder"
}
]
}
}
@@ -0,0 +1,13 @@
{
"@ns": "http://midpoint.evolveum.com/xml/ns/public/common/api-types-3",
"policyItemsDefinition": {
"policyItemDefinition": [
{
"target": {
"path": "credentials/securityQuestions/questionAnswer[1]/questionAnswer"
},
"value": "another"
}
]
}
}

0 comments on commit a682c34

Please sign in to comment.