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
KaterynaHonchar committed Sep 18, 2020
2 parents d6f59f5 + bc51e40 commit 4bc7b1f
Show file tree
Hide file tree
Showing 27 changed files with 822 additions and 953 deletions.
Expand Up @@ -111,7 +111,7 @@ public abstract class ResourceContentPanel extends Panel {
private static final Trace LOGGER = TraceManager.getTrace(ResourceContentPanel.class);

private static final String DOT_CLASS = ResourceContentTabPanel.class.getName() + ".";
private static final String OPERATION_SEARCH_TASKS_FOR_RESOURCE = DOT_CLASS + "seachTasks";
private static final String OPERATION_SEARCH_TASKS_FOR_RESOURCE = DOT_CLASS + "searchTasks";
private static final String OPERATION_CHANGE_OWNER = DOT_CLASS + "changeOwner";
private static final String OPERATION_LOAD_SHADOW_OWNER = DOT_CLASS + "loadOwner";
private static final String OPERATION_UPDATE_STATUS = DOT_CLASS + "updateStatus";
Expand Down
Expand Up @@ -61,7 +61,7 @@ public class ResourceDetailsTabPanel extends Panel {
private static final Trace LOGGER = TraceManager.getTrace(ResourceDetailsTabPanel.class);

private static final String DOT_CLASS = ResourceDetailsTabPanel.class.getName() + ".";
private static final String OPERATION_SEARCH_TASKS_FOR_RESOURCE = DOT_CLASS + "seachTasks";
private static final String OPERATION_SEARCH_TASKS_FOR_RESOURCE = DOT_CLASS + "searchTasks";

public static final String ID_LAST_AVAILABILITY_STATUS = "lastStatus";
private static final String ID_SOURCE_TARGET = "sourceTarget";
Expand Down
Expand Up @@ -65,4 +65,16 @@ public AbstractModuleFactory findModelFactory(AbstractAuthenticationModuleType c
return factory;
}

public <T extends AbstractModuleFactory> T findModelFactoryByClass(Class<T> clazz) {

Optional<T> opt = (Optional<T>) moduleFactories.stream().filter(f -> f.getClass().equals(clazz)).findFirst();
if (!opt.isPresent()) {
LOGGER.trace("No factory found for class {}", clazz);
return null;
}
T factory = opt.get();
LOGGER.trace("Found component factory {} for class {}", factory, clazz);
return factory;
}

}
Expand Up @@ -66,7 +66,7 @@ private ModuleWebSecurityConfig createModule(ModuleWebSecurityConfiguration conf
}

private AuthenticationProvider createProvider() {
return new ClusterProvider();
return getObjectObjectPostProcessor().postProcess(new ClusterProvider());
}

private ModuleAuthentication createEmptyModuleAuthentication(AbstractAuthenticationModuleType moduleType, ModuleWebSecurityConfiguration configuration) {
Expand Down
Expand Up @@ -7,6 +7,8 @@
package com.evolveum.midpoint.web.security.filter;

import com.evolveum.midpoint.model.api.authentication.AuthenticationModuleNameConstants;
import com.evolveum.midpoint.model.api.authentication.MidpointAuthentication;
import com.evolveum.midpoint.model.api.authentication.ModuleAuthentication;
import com.evolveum.midpoint.util.logging.Trace;
import com.evolveum.midpoint.util.logging.TraceManager;
import com.evolveum.midpoint.web.security.BasicMidPointAuthenticationSuccessHandler;
Expand All @@ -15,6 +17,7 @@
import org.springframework.security.authentication.*;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.security.web.authentication.NullRememberMeServices;
Expand All @@ -28,6 +31,7 @@
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
import java.util.List;

/**
* @author skublik
Expand Down Expand Up @@ -89,7 +93,13 @@ protected void doFilterInternal(HttpServletRequest request,

this.rememberMeServices.loginFail(request, response);

this.getAuthenticationEntryPoint().commence(request, response, failed);
StringBuilder sb = new StringBuilder();
sb.append(AuthenticationModuleNameConstants.CLUSTER).append(" realm=\"midpoint\"");
response.setHeader("WWW-Authenticate",sb.toString());
response.sendError(HttpServletResponse.SC_UNAUTHORIZED);
response.getWriter().write(" test error ");
response.getWriter().flush();
response.getWriter().close();

return;
}
Expand Down
Expand Up @@ -150,13 +150,20 @@ private void doFilterInternal(ServletRequest request, ServletResponse response,
throw new AuthenticationServiceException("Couldn't find filters for sequence " + sequence.getName());
}

int indexOfProcessingModule = getIndexOfActualProcessingModule(mpAuthentication, httpRequest);
int indexOfProcessingModule;

resolveErrorWithMoreModules(mpAuthentication, httpRequest);

if (needRestartAuthFlow(indexOfProcessingModule)) {
indexOfProcessingModule = restartAuthFlow(mpAuthentication, httpRequest, sequence, authModules);
if (SecurityUtils.isSpecificSequence(httpRequest)){
indexOfProcessingModule = 0;
createMpAuthentication(httpRequest, sequence, authModules);
mpAuthentication = (MidpointAuthentication) SecurityContextHolder.getContext().getAuthentication();
} else {
indexOfProcessingModule = getIndexOfActualProcessingModule(mpAuthentication, httpRequest);
if (needRestartAuthFlow(indexOfProcessingModule)) {
indexOfProcessingModule = restartAuthFlow(httpRequest, sequence, authModules);
mpAuthentication = (MidpointAuthentication) SecurityContextHolder.getContext().getAuthentication();
}
}

if (mpAuthentication.getAuthenticationChannel() == null) {
Expand All @@ -172,14 +179,19 @@ private boolean needRestartAuthFlow(int indexOfProcessingModule) {
return indexOfProcessingModule == -1;
}

private int restartAuthFlow(MidpointAuthentication mpAuthentication, HttpServletRequest httpRequest, AuthenticationSequenceType sequence, List<AuthModule> authModules) {
private int restartAuthFlow(HttpServletRequest httpRequest, AuthenticationSequenceType sequence, List<AuthModule> authModules) {
createMpAuthentication(httpRequest,sequence,authModules);
MidpointAuthentication mpAuthentication = (MidpointAuthentication) SecurityContextHolder.getContext().getAuthentication();
return mpAuthentication.resolveParallelModules(httpRequest, 0);
}

private void createMpAuthentication(HttpServletRequest httpRequest, AuthenticationSequenceType sequence, List<AuthModule> authModules) {
SecurityContextHolder.getContext().setAuthentication(null);
SecurityContextHolder.getContext().setAuthentication(new MidpointAuthentication(sequence));
mpAuthentication = (MidpointAuthentication) SecurityContextHolder.getContext().getAuthentication();
MidpointAuthentication mpAuthentication = (MidpointAuthentication) SecurityContextHolder.getContext().getAuthentication();
mpAuthentication.setAuthModules(authModules);
mpAuthentication.setSessionId(httpRequest.getSession(false) != null ? httpRequest.getSession(false).getId() : RandomStringUtils.random(30, true, true).toUpperCase());
mpAuthentication.addAuthentications(authModules.get(0).getBaseModuleAuthentication());
return mpAuthentication.resolveParallelModules(httpRequest, 0);
}

private void resolveErrorWithMoreModules(MidpointAuthentication mpAuthentication, HttpServletRequest httpRequest) {
Expand Down Expand Up @@ -322,16 +334,5 @@ public void doFilter(ServletRequest request, ServletResponse response)
}
}
}

public interface FilterChainValidator {
void validate(MidpointAuthFilter filterChainProxy);
}

private static class NullFilterChainValidator implements MidpointAuthFilter.FilterChainValidator {
@Override
public void validate(MidpointAuthFilter filterChainProxy) {
}
}

}

Expand Up @@ -55,7 +55,7 @@ protected Authentication internalAuthentication(Authentication authentication, L
Authentication token;
if (authentication instanceof ClusterAuthenticationToken) {
String enteredPassword = (String) authentication.getCredentials();
if (!nodeAuthenticator.authenticate(null, enteredUsername, enteredPassword, "?")) {
if (!nodeAuthenticator.authenticate(null, enteredUsername, enteredPassword, "node authentication")) {
throw new AuthenticationServiceException("web.security.flexAuth.cluster.auth.null");
} else {
token = SecurityContextHolder.getContext().getAuthentication();
Expand All @@ -65,10 +65,8 @@ protected Authentication internalAuthentication(Authentication authentication, L
throw new AuthenticationServiceException("web.security.provider.unavailable");
}

MidPointPrincipal principal = (MidPointPrincipal)token.getPrincipal();

LOGGER.debug("User '{}' authenticated ({}), authorities: {}", authentication.getPrincipal(),
authentication.getClass().getSimpleName(), principal.getAuthorities());
LOGGER.debug("Node '{}' authenticated}", authentication.getPrincipal());
token.setAuthenticated(true);
return token;

} catch (AuthenticationException e) {
Expand Down
Expand Up @@ -94,8 +94,12 @@ public Authentication authenticate(Authentication originalAuthentication) throws
if (actualAuthentication instanceof MidpointAuthentication) {
MidpointAuthentication mpAuthentication = (MidpointAuthentication) actualAuthentication;
ModuleAuthentication moduleAuthentication = getProcessingModule(mpAuthentication);
MidPointPrincipal principal = (MidPointPrincipal) token.getPrincipal();
token = createNewAuthenticationToken(token, mpAuthentication.getAuthenticationChannel().resolveAuthorities(principal.getAuthorities()));
if (token.getPrincipal() instanceof MidPointPrincipal) {
MidPointPrincipal principal = (MidPointPrincipal) token.getPrincipal();
token = createNewAuthenticationToken(token, mpAuthentication.getAuthenticationChannel().resolveAuthorities(principal.getAuthorities()));
} else {
token = createNewAuthenticationToken(token, token.getAuthorities());
}
writeAutentication(processingAuthentication, mpAuthentication, moduleAuthentication, token);

return mpAuthentication;
Expand Down
Expand Up @@ -198,9 +198,8 @@ public static AuthenticationSequenceType getSequenceByPath(HttpServletRequest ht
}
String[] partsOfLocalPath = stripStartingSlashes(localePath).split("/");

AuthenticationSequenceType specificSequence = getSpecificSequence(httpRequest);
if (specificSequence != null) {
return specificSequence;
if (isSpecificSequence(httpRequest)) {
return getSpecificSequence(httpRequest);
}

List<AuthenticationSequenceType> sequences = getSequencesForNodeGroups(nodeGroups, authenticationPolicy);
Expand Down Expand Up @@ -319,13 +318,30 @@ private static AuthenticationSequenceType getSpecificSequence(HttpServletRequest
sequence.setName(AuthenticationModuleNameConstants.CLUSTER);
AuthenticationSequenceChannelType seqChannel = new AuthenticationSequenceChannelType();
seqChannel.setUrlSuffix(AuthenticationModuleNameConstants.CLUSTER.toLowerCase());
seqChannel.setChannelId(SchemaConstants.CHANNEL_REST_URI);
sequence.setChannel(seqChannel);
return sequence;
}
}
}
return null;
}

public static boolean isSpecificSequence(HttpServletRequest httpRequest) {
String localePath = httpRequest.getRequestURI().substring(httpRequest.getContextPath().length());
String channel = searchChannelByPath(localePath);
if (SchemaConstants.CHANNEL_REST_URI.equals(channel)) {
String header = httpRequest.getHeader("Authorization");
if (header != null) {
String type = header.split(" ")[0];
if (AuthenticationModuleNameConstants.CLUSTER.toLowerCase().equals(type.toLowerCase())) {
return true;
}
}
}
return false;
}

private static AuthenticationSequenceType searchSequence(String comparisonAttribute, boolean inputIsChannel, List<AuthenticationSequenceType> sequences) {
Validate.notBlank(comparisonAttribute, "Comparison attribute for searching of sequence is blank");
for (AuthenticationSequenceType sequence : sequences) {
Expand Down Expand Up @@ -372,14 +388,14 @@ public static List<AuthModule> buildModuleFilters(AuthModuleRegistryImpl authReg
CredentialsPolicyType credentialPolicy, Map<Class<?>, Object> sharedObjects,
AuthenticationChannel authenticationChannel) {
Validate.notNull(authRegistry, "Registry for module factories is null");
Validate.notEmpty(sequence.getModule(), "Sequence " + sequence.getName() + " don't contains authentication modules");

List<AuthModule> specificModules = getSpecificModuleFilter(sequence.getChannel().getUrlSuffix(), request,
sharedObjects, authenticationModulesType, credentialPolicy);
if (specificModules != null) {
return specificModules;
if (isSpecificSequence(request)) {
return getSpecificModuleFilter(authRegistry, sequence.getChannel().getUrlSuffix(), request,
sharedObjects, authenticationModulesType, credentialPolicy);
}

Validate.notEmpty(sequence.getModule(), "Sequence " + sequence.getName() + " don't contains authentication modules");

List<AuthenticationSequenceModuleType> sequenceModules = SecurityPolicyUtil.getSortedModules(sequence);
List<AuthModule> authModules = new ArrayList<>();
sequenceModules.forEach(sequenceModule -> {
Expand All @@ -399,7 +415,7 @@ public static List<AuthModule> buildModuleFilters(AuthModuleRegistryImpl authReg
return authModules;
}

private static List<AuthModule> getSpecificModuleFilter(String urlSuffix, HttpServletRequest httpRequest, Map<Class<?>, Object> sharedObjects,
private static List<AuthModule> getSpecificModuleFilter(AuthModuleRegistryImpl authRegistry, String urlSuffix, HttpServletRequest httpRequest, Map<Class<?>, Object> sharedObjects,
AuthenticationModulesType authenticationModulesType, CredentialsPolicyType credentialPolicy) {
String localePath = httpRequest.getRequestURI().substring(httpRequest.getContextPath().length());
String channel = searchChannelByPath(localePath);
Expand All @@ -409,8 +425,7 @@ private static List<AuthModule> getSpecificModuleFilter(String urlSuffix, HttpSe
String type = header.split(" ")[0];
if (AuthenticationModuleNameConstants.CLUSTER.toLowerCase().equals(type.toLowerCase())) {
List<AuthModule> authModules = new ArrayList<>();
WebApplicationContext context = ContextLoader.getCurrentWebApplicationContext();
HttpClusterModuleFactory factory = context.getBean(HttpClusterModuleFactory.class);
HttpClusterModuleFactory factory = authRegistry.findModelFactoryByClass(HttpClusterModuleFactory.class);
AbstractAuthenticationModuleType module = new AbstractAuthenticationModuleType() {
};
module.setName(AuthenticationModuleNameConstants.CLUSTER.toLowerCase() + "-module");
Expand Down
Expand Up @@ -142,7 +142,6 @@ public static List<AuthenticationSequenceModuleType> getSortedModules(Authentica
Validate.notNull(sequence);
ArrayList<AuthenticationSequenceModuleType> modules = new ArrayList<>(sequence.getModule());
Validate.notNull(modules);
Validate.notEmpty(modules);
Comparator<AuthenticationSequenceModuleType> comparator =
(f1, f2) -> {
Integer f1Order = f1.getOrder();
Expand Down
Expand Up @@ -601,17 +601,18 @@ public List<AuditEventRecordType> searchObjectFromCollection(CollectionRefSpecif

private <T extends Object> List<T> evaluateCondition(ExpressionType condition, List<T> values, Task task, OperationResult result)
throws CommunicationException, ObjectNotFoundException, SchemaException, SecurityViolationException, ConfigurationException, ExpressionEvaluationException {
List<T> newValues = new ArrayList();
for (T value : values) {
Iterator<T> iterator = values.iterator();
while (iterator.hasNext()) {
T value = iterator.next();
ExpressionVariables variables = new ExpressionVariables();
variables.put(ExpressionConstants.VAR_OBJECT, value, value.getClass());
PrismPropertyValue<Boolean> conditionValue = ExpressionUtil.evaluateCondition(variables, condition, null, expressionFactory,
"Evaluate condition", task, result);
if (conditionValue != null && Boolean.TRUE.equals(conditionValue.getRealValue())) {
newValues.add(value);
if (conditionValue == null || Boolean.FALSE.equals(conditionValue.getRealValue())) {
iterator.remove();
}
}
return newValues;
return values;
}

@Override
Expand Down
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2010-2020 Evolveum and contributors
* Copyright (C) 2010-2020 Evolveum and contributors
*
* This work is dual-licensed under the Apache License 2.0
* and European Union Public License. See LICENSE file for details.
Expand Down Expand Up @@ -76,7 +76,8 @@ public class TestImportRecon extends AbstractInitializedModelIntegrationTest {

private static final File TEST_DIR = new File("src/test/resources/sync");

private static final TestResource USER_IMPORTER = new TestResource(TEST_DIR, "user-importer.xml", "00000000-1111-1111-1111-000000000002");
private static final TestResource<UserType> USER_IMPORTER = new TestResource<>(
TEST_DIR, "user-importer.xml", "00000000-1111-1111-1111-000000000002");

private static final String ACCOUNT_OTIS_NAME = "otis";
private static final String ACCOUNT_OTIS_FULLNAME = "Otis";
Expand Down Expand Up @@ -2532,6 +2533,7 @@ public void test520ReconResourceDummyFilter() throws Exception {

OperationStatsType statistics = taskAfter.getStoredOperationStats();
SynchronizationInformationType syncInfo = statistics.getSynchronizationInformation();
// TODO: sometimes fails with: java.lang.AssertionError: expected:<12> but was:<0>
assertEquals(17 - 3 - 2, syncInfo.getCountLinked()); //total (17) - filtered (3)- protectected (2)
}

Expand Down
Expand Up @@ -839,8 +839,7 @@ public void test032ResourceAndConnectorCaching() throws Exception {
@Test
public void test034ResourceAndConnectorCachingForceFresh() throws Exception {
// GIVEN
OperationResult result = new OperationResult(AbstractBasicDummyTest.class.getName()
+ ".test011ResourceAndConnectorCachingForceFresh");
OperationResult result = createOperationResult();
ConnectorInstance configuredConnectorInstance = resourceManager.getConfiguredConnectorInstance(
resource, ReadCapabilityType.class, false, result);
assertNotNull("No configuredConnectorInstance", configuredConnectorInstance);
Expand Down

0 comments on commit 4bc7b1f

Please sign in to comment.