Skip to content

Commit

Permalink
* cleanup correlation service (better spacing and annotations),
Browse files Browse the repository at this point in the history
* improving username recovery page
* support for cadidate owner oids as a parameter for correlate method. Based on this input, the query is refined to search only in the set of the candidates.
  • Loading branch information
katkav committed Aug 1, 2023
1 parent 7b434ed commit b4bf32c
Show file tree
Hide file tree
Showing 19 changed files with 217 additions and 134 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -119,18 +119,19 @@ protected CorrelatorConfigDto load() {
}

private List<VerificationAttributeDto> getCorrelationAttributePaths(String correlatorName) {
PathSet pathList;
PathSet paths;
try {
Task task = createAnonymousTask(OPERATION_DETERMINE_CORRELATOR_SETTINGS);
pathList = getCorrelationService().determineCorrelatorConfiguration(new CorrelatorDiscriminator(correlatorName, CorrelationUseType.USERNAME_RECOVERY), archetypeOid, task, task.getResult());
paths = getCorrelationService().determineCorrelatorConfiguration(
new CorrelatorDiscriminator(correlatorName, CorrelationUseType.USERNAME_RECOVERY), archetypeOid, task, task.getResult());
} catch (Exception e) {
LoggingUtils.logException(LOGGER, "Couldn't determine correlator configuration", e);
pathList = new PathSet();
paths = new PathSet();
}

return pathList
return paths
.stream()
.map(p -> new VerificationAttributeDto(new ItemPathType(p)))
.map(path -> new VerificationAttributeDto(new ItemPathType(path)))
.collect(Collectors.toList());
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,11 @@
<body>
<wicket:extend>
<div wicket:id="foundUsers"/>

<a class="text-center login-panel-control mt-2" style="display: inline-block;" wicket:id="back">
<i class="fas fa-arrow-left mr-2"></i>
<wicket:message key="PageEmailNonce.backButtonLabel"/>
</a>
</wicket:extend>

</body>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,13 @@
import com.evolveum.midpoint.gui.impl.page.login.AbstractPageLogin;
import com.evolveum.midpoint.security.api.AuthorizationConstants;
import com.evolveum.midpoint.security.api.MidPointPrincipal;
import com.evolveum.midpoint.web.component.AjaxButton;
import com.evolveum.midpoint.web.component.form.MidpointForm;
import com.evolveum.midpoint.web.page.error.PageError;
import com.evolveum.midpoint.web.page.self.PageSelf;

import org.apache.wicket.RestartResponseException;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.markup.html.basic.Label;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
Expand All @@ -35,6 +38,7 @@
public class PageUsernameRecovery extends AbstractPageLogin {

private static final String ID_FOUND_USERS = "foundUsers";
private static final String ID_BACK_BUTTON = "back";

public PageUsernameRecovery() {
super();
Expand All @@ -55,6 +59,17 @@ protected void initCustomLayout() {
Label label = new Label(ID_FOUND_USERS, getString("PageUsernameRecovery.noUserFound"));
add(label);
}

AjaxButton backButton = new AjaxButton(ID_BACK_BUTTON) {
private static final long serialVersionUID = 1L;

@Override
public void onClick(AjaxRequestTarget target) {
cancelPerformed();
}
};
backButton.setOutputMarkupId(true);
add(backButton);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,25 +10,28 @@
import com.evolveum.midpoint.xml.ns._public.common.common_3.CompositeCorrelatorType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.CorrelationUseType;

import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.Objects;

public class CorrelatorDiscriminator {

private String correlatorIdentifier;
private CorrelationUseType use;
/**
* Correlator identifier. It is either a name of the correlator object or null.
* Null is supported for synchronization.
*/
@Nullable private final String correlatorIdentifier;
@NotNull private final CorrelationUseType use;

public CorrelatorDiscriminator(String correlatorIdentifier, CorrelationUseType use) {
public CorrelatorDiscriminator(@Nullable String correlatorIdentifier, @NotNull CorrelationUseType use) {
this.correlatorIdentifier = correlatorIdentifier;
this.use = use;
}

public boolean match(CompositeCorrelatorType correlatorType) {
if (correlatorType == null) {
return false;
}

return Objects.equals(correlatorType.getName(), correlatorIdentifier)
&& correlatorType.getUse() == use;
public boolean match(@NotNull CompositeCorrelatorType correlator) {
return Objects.equals(correlator.getName(), correlatorIdentifier)
&& correlator.getUse() == use;
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,11 @@ public class ObjectTemplateTypeUtil {
return null;
}
ObjectTemplateCorrelationType correlation = template.getCorrelation();
List<CompositeCorrelatorType> correlators = correlation != null ? correlation.getCorrelators() : null;
if (correlators == null) {
return null;
}
return correlators.stream().filter(discriminator::match).findFirst().orElse(null);
List<CompositeCorrelatorType> correlators = correlation != null ? correlation.getCorrelators() : List.of();
return correlators.stream()
.filter(discriminator::match)
.findFirst()
.orElse(null);
}

public static @Nullable ObjectTemplateItemDefinitionType findItemDefinition(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,10 @@ public void recordModuleAuthenticationAttemptFailure(MidPointPrincipal principal
}

public void recordSequenceAuthenticationSuccess(MidPointPrincipal principal, ConnectionEnvironment connEnv) {
if (principal == null) {
//TODO logging?
return;
}
FocusType focusBefore = principal.getFocus().clone();

AuthenticationBehavioralDataType behavior = AuthUtil.getOrCreateBehavioralDataForSequence(principal, connEnv.getSequenceIdentifier());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,6 @@ public AuthModule<MA> createAuthModule(MT moduleType, String sequenceSuffix,
SecurityFilterChain filter = http.build();
postProcessFilter(filter, moduleConfigurer);


MA moduleAuthentication = createEmptyModuleAuthentication(moduleType, moduleConfigurer.getConfiguration(), sequenceModule, request);
moduleAuthentication.setFocusType(moduleType.getFocusType());

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,12 @@ public boolean match(AbstractAuthenticationModuleType moduleType, Authentication

@Override
protected CorrelationModuleWebSecurityConfigurer createModuleConfigurer(CorrelationAuthenticationModuleType moduleType, String sequenceSuffix, AuthenticationChannel authenticationChannel, ObjectPostProcessor<Object> objectPostProcessor, ServletRequest request) {
return new CorrelationModuleWebSecurityConfigurer(moduleType, sequenceSuffix, authenticationChannel,
objectPostProcessor, request,
return new CorrelationModuleWebSecurityConfigurer(
moduleType,
sequenceSuffix,
authenticationChannel,
objectPostProcessor,
request,
new CorrelationProvider());
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,23 @@
import com.evolveum.midpoint.authentication.api.config.CorrelationModuleAuthentication;
import com.evolveum.midpoint.authentication.api.util.AuthenticationModuleNameConstants;
import com.evolveum.midpoint.authentication.impl.util.ModuleType;
import com.evolveum.midpoint.model.api.correlator.CandidateOwner;
import com.evolveum.midpoint.model.api.correlator.CandidateOwnersMap;
import com.evolveum.midpoint.xml.ns._public.common.common_3.AuthenticationSequenceModuleType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.CorrelationModuleConfigurationType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.ModuleItemConfigurationType;

import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

public class CorrelationModuleAuthenticationImpl extends ModuleAuthenticationImpl implements CorrelationModuleAuthentication {

private List<CorrelationModuleConfigurationType> correlators;
private int currentProcessingCorrelator;

private CandidateOwnersMap candidateOwners = new CandidateOwnersMap();

public CorrelationModuleAuthenticationImpl(AuthenticationSequenceModuleType sequenceModule) {
super(AuthenticationModuleNameConstants.CORRELATION, sequenceModule);
setType(ModuleType.LOCAL);
Expand Down Expand Up @@ -52,4 +58,15 @@ public boolean isLastCorrelator() {
public void setNextCorrelator() {
currentProcessingCorrelator++;
}

public void addCandidateOwners(CandidateOwnersMap map) {
candidateOwners.mergeWith(map);
}

public Set<String> getCandidateOids() {
return candidateOwners.values()
.stream()
.map(CandidateOwner::getOid)
.collect(Collectors.toSet());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import com.evolveum.midpoint.authentication.api.config.MidpointAuthentication;
import com.evolveum.midpoint.authentication.api.config.ModuleAuthentication;
import com.evolveum.midpoint.authentication.api.util.AuthUtil;
import com.evolveum.midpoint.authentication.impl.module.authentication.CorrelationModuleAuthenticationImpl;
import com.evolveum.midpoint.authentication.impl.module.authentication.FocusIdentificationModuleAuthentication;
import com.evolveum.midpoint.authentication.impl.module.authentication.token.CorrelationVerificationToken;
import com.evolveum.midpoint.authentication.impl.module.authentication.token.FocusVerificationToken;
Expand All @@ -21,6 +22,7 @@
import com.evolveum.midpoint.model.api.context.PasswordAuthenticationContext;
import com.evolveum.midpoint.model.api.correlation.CompleteCorrelationResult;
import com.evolveum.midpoint.model.api.correlation.CorrelationService;
import com.evolveum.midpoint.model.api.correlator.CandidateOwnersMap;
import com.evolveum.midpoint.model.api.correlator.CorrelatorContext;
import com.evolveum.midpoint.model.api.correlator.CorrelatorFactoryRegistry;
import com.evolveum.midpoint.prism.path.ItemPath;
Expand All @@ -47,6 +49,7 @@
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;

public class CorrelationProvider extends MidPointAbstractAuthenticationProvider<PasswordAuthenticationContext> {

Expand Down Expand Up @@ -85,66 +88,35 @@ protected Authentication internalAuthentication(Authentication authentication, L

try {
Authentication token = null;
if (authentication instanceof CorrelationVerificationToken) {

CompleteCorrelationResult correlationResult;
if (authentication instanceof CorrelationVerificationToken correlationVerificationToken) {
try {

Authentication processingAuthentication = SecurityUtil.getAuthentication();
String archetypeOid;
if (processingAuthentication instanceof MidpointAuthentication mpAuthentication) {
archetypeOid = mpAuthentication.getArchetypeOid();
} else {
archetypeOid = null;
ModuleAuthentication moduleAuthentication = AuthUtil.getProcessingModule();
if (!(moduleAuthentication instanceof CorrelationModuleAuthenticationImpl correlationModuleAuthentication)) {
LOGGER.error("Correlation module authentication is not set");
throw new AuthenticationServiceException("web.security.provider.unavailable");
}

correlationResult = securityContextManager.runPrivileged(() -> {
Task task = taskManager.createTaskInstance("correlate");
task.setChannel(SchemaConstants.CHANNEL_LOGIN_RECOVERY_URI);

CorrelationVerificationToken correlationToken = (CorrelationVerificationToken) authentication;
try {

CompleteCorrelationResult result = correlationService.correlate(correlationToken.getPreFocus(focusType),
archetypeOid,
new CorrelatorDiscriminator(correlationToken.getCorrelatorName(), CorrelationUseType.USERNAME_RECOVERY),
task, task.getResult());
return result;//.getOwner();
} catch (SchemaException | ExpressionEvaluationException | CommunicationException |
SecurityViolationException | ConfigurationException | ObjectNotFoundException e) {
LOGGER.error("Unsupported authentication {}", authentication);

ModuleAuthentication moduleAuthentication = AuthUtil.getProcessingModule();
if (moduleAuthentication instanceof CorrelationModuleAuthentication correlationModuleAuthentication) {
//move to another correlator if exist?
}
throw new TunnelException(e);
}
});

CompleteCorrelationResult correlationResult = correlate(correlationVerificationToken,
determineArchetypeOid(),
correlationModuleAuthentication.getCandidateOids(),
focusType);
ObjectType owner = correlationResult.getOwner();

//TODO save result and find a way how to use it when next correlators run

if (owner != null) {
try {
MidPointPrincipal principal = focusProfileService.getPrincipalByOid(owner.getOid(), focusType);
return new UsernamePasswordAuthenticationToken(principal, null);
} catch (ObjectNotFoundException | SchemaException | CommunicationException | ConfigurationException |
SecurityViolationException | ExpressionEvaluationException e) {
throw new RuntimeException(e);
//TODO
}

return createAuthenticationToken(owner, focusType);
}

CandidateOwnersMap ownersMap = correlationResult.getCandidateOwnersMap();
correlationModuleAuthentication.addCandidateOwners(ownersMap);

return authentication;
} catch (Exception e) {
LOGGER.error("Cannot correlate user, {}", e.getMessage(), e);
throw new AuthenticationServiceException("web.security.provider.unavailable");
}




} else {
LOGGER.error("Unsupported authentication {}", authentication);
throw new AuthenticationServiceException("web.security.provider.unavailable");
Expand All @@ -155,6 +127,42 @@ protected Authentication internalAuthentication(Authentication authentication, L
}
}

private String determineArchetypeOid() {
Authentication processingAuthentication = SecurityUtil.getAuthentication();
if (processingAuthentication instanceof MidpointAuthentication mpAuthentication) {
return mpAuthentication.getArchetypeOid();
}
return null;
}

private Authentication createAuthenticationToken(ObjectType owner, Class<? extends FocusType> focusType) {
try {
MidPointPrincipal principal = focusProfileService.getPrincipalByOid(owner.getOid(), focusType);
return new UsernamePasswordAuthenticationToken(principal, null);
} catch (ObjectNotFoundException | SchemaException | CommunicationException | ConfigurationException |
SecurityViolationException | ExpressionEvaluationException e) {
throw new RuntimeException(e);
//TODO
}
}

private CompleteCorrelationResult correlate(
CorrelationVerificationToken correlationToken,
String archetypeOid,
Set<String> candidatesOids,
Class<? extends FocusType> focusType) throws SchemaException, ExpressionEvaluationException, CommunicationException, SecurityViolationException, ConfigurationException, ObjectNotFoundException {
Task task = taskManager.createTaskInstance("correlate");
task.setChannel(SchemaConstants.CHANNEL_LOGIN_RECOVERY_URI);

//TODO cadidateOids as a parameter, + define somehow threshold - how many users migh be returned from the correlation
return correlationService.correlate(
correlationToken.getPreFocus(focusType),
archetypeOid,
candidatesOids,
new CorrelatorDiscriminator(correlationToken.getCorrelatorName(), CorrelationUseType.USERNAME_RECOVERY),
task, task.getResult());
}

@Override
protected Authentication createNewAuthenticationToken(Authentication actualAuthentication, Collection<? extends GrantedAuthority> newAuthorities) {
if (actualAuthentication instanceof UsernamePasswordAuthenticationToken) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,8 +93,14 @@ private AuthModule<MA> createAuthModule(AuthenticationSequenceModuleType sequenc
AbstractAuthenticationModuleType module = getModuleByIdentifier(sequenceModuleIdentifier, authenticationModulesType);
ModuleFactory<AbstractAuthenticationModuleType, MA> moduleFactory = authRegistry.findModuleFactory(module, authenticationChannel);

return moduleFactory.createAuthModule(module, sequence.getChannel().getUrlSuffix(), request,
sharedObjects, authenticationModulesType, credentialPolicy, authenticationChannel, sequenceModule);
return moduleFactory.createAuthModule(module,
sequence.getChannel().getUrlSuffix(),
request,
sharedObjects,
authenticationModulesType,
credentialPolicy,
authenticationChannel,
sequenceModule);

} catch (Exception e) {
LOGGER.error("Couldn't build filter for module moduleFactory", e);
Expand Down

0 comments on commit b4bf32c

Please sign in to comment.