Skip to content

Commit

Permalink
finishing pst-authentication - forced roles..
Browse files Browse the repository at this point in the history
  • Loading branch information
katkav committed Jul 10, 2018
1 parent 6cce7be commit eef45f7
Show file tree
Hide file tree
Showing 21 changed files with 214 additions and 55 deletions.
Expand Up @@ -33,9 +33,11 @@
import com.evolveum.midpoint.prism.path.ItemPath;
import com.evolveum.midpoint.schema.constants.SchemaConstants;
import com.evolveum.midpoint.schema.result.OperationResult;
import com.evolveum.midpoint.security.api.AuthorizationConstants;
import com.evolveum.midpoint.security.api.MidPointPrincipal;
import com.evolveum.midpoint.security.api.UserProfileService;
import com.evolveum.midpoint.task.api.Task;
import com.evolveum.midpoint.util.exception.ObjectNotFoundException;
import com.evolveum.midpoint.util.exception.SchemaException;
import com.evolveum.midpoint.util.logging.LoggingUtils;
import com.evolveum.midpoint.util.logging.Trace;
Expand All @@ -49,17 +51,18 @@
import com.evolveum.midpoint.web.component.prism.ObjectWrapperFactory;
import com.evolveum.midpoint.web.component.prism.PrismPanel;
import com.evolveum.midpoint.web.model.ContainerWrapperListFromObjectWrapperModel;
import com.evolveum.midpoint.web.page.admin.users.PageAdminUsers;
import com.evolveum.midpoint.web.page.login.PageAbstractFlow;
import com.evolveum.midpoint.web.resource.img.ImgResources;
import com.evolveum.midpoint.web.security.SecurityUtils;
import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectReferenceType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.UserType;

@PageDescriptor(urls = {@Url(mountUrl = "/self/postAuthentication")},
@PageDescriptor(urls = {@Url(mountUrl = "/self/postAuthentication", matchUrlForSecurity="/self/postAuthentication")},
action = {
@AuthorizationAction(actionUri = PageSelf.AUTH_SELF_ALL_URI,
label = PageSelf.AUTH_SELF_ALL_LABEL,
description = PageSelf.AUTH_SELF_ALL_DESCRIPTION)
@AuthorizationAction(actionUri = AuthorizationConstants.AUTZ_UI_SELF_POST_AUTHENTICATION_URL,
label = "PagePostAuthentication.auth.postAuthentication.label",
description = "PagePostAuthentication.auth.postAuthentication.description"),
}
)
public class PagePostAuthentication extends PageAbstractFlow {
Expand All @@ -76,11 +79,6 @@ public class PagePostAuthentication extends PageAbstractFlow {
private IModel<UserType> userModel;
private ObjectWrapper<UserType> objectWrapper;

//TODO: where is the correct palce?
@SpringBean(name = "userDetailsService")
private UserProfileService userProfileService;


public PagePostAuthentication(PageParameters pageParameters) {
super(pageParameters);
}
Expand Down Expand Up @@ -174,15 +172,19 @@ protected void submitRegistration(AjaxRequestTarget target) {
}

result.computeStatus();

showResult(result, true);
if (!result.isAcceptable()) {
showResult(result);
target.add(PagePostAuthentication.this);
} else {
MidPointPrincipal principal = SecurityUtils.getPrincipalUser();
getModelInteractionService().refreshPrincipal(principal.getUsername());
try {
getModelInteractionService().refreshPrincipal(principal.getOid());
navigateToNext(getMidpointApplication().getHomePage());
} catch (ObjectNotFoundException | SchemaException e) {
LOGGER.error("Errpr while refreshing user: ", e);
target.add(PagePostAuthentication.this);
}

navigateToNext(getMidpointApplication().getHomePage());
}

target.add(getFeedbackPanel());
Expand Down
Expand Up @@ -19,7 +19,7 @@
import javax.xml.datatype.XMLGregorianCalendar;

import com.evolveum.midpoint.schema.constants.SchemaConstants;
import com.evolveum.midpoint.schema.util.LifecyleUtil;
import com.evolveum.midpoint.schema.util.LifecycleUtil;
import com.evolveum.midpoint.xml.ns._public.common.common_3.ActivationStatusType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.ActivationType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.LifecycleStateModelType;
Expand Down Expand Up @@ -145,7 +145,7 @@ public void computeEffective(String lifecycleStatus, ActivationType activationTy
}

public boolean lifecycleHasActiveAssignments(String lifecycleStatus, LifecycleStateModelType stateModel) {
LifecycleStateType stateDefinition = LifecyleUtil.findStateDefinition(stateModel, lifecycleStatus);
LifecycleStateType stateDefinition = LifecycleUtil.findStateDefinition(stateModel, lifecycleStatus);
if (stateDefinition == null) {
return defaultLifecycleHasActiveAssignments(lifecycleStatus, stateModel);
}
Expand Down Expand Up @@ -175,7 +175,7 @@ private boolean defaultLifecycleHasActiveAssignments(String lifecycleStatus, Lif


public ActivationStatusType getForcedLifecycleActivationStatus(String lifecycleStatus, LifecycleStateModelType stateModel) {
LifecycleStateType stateDefinition = LifecyleUtil.findStateDefinition(stateModel, lifecycleStatus);
LifecycleStateType stateDefinition = LifecycleUtil.findStateDefinition(stateModel, lifecycleStatus);
if (stateDefinition == null) {
return getHardcodedForcedLifecycleActivationStatus(lifecycleStatus);
}
Expand Down
@@ -0,0 +1,26 @@
package com.evolveum.midpoint.schema;

import com.evolveum.midpoint.prism.query.ObjectFilter;
import com.evolveum.midpoint.xml.ns._public.common.common_3.AbstractRoleType;

public class VirtualAssignmenetSpecification<R extends AbstractRoleType> {

private ObjectFilter filter;
private Class<R> type;

public ObjectFilter getFilter() {
return filter;
}

public Class<R> getType() {
return type;
}

public void setFilter(ObjectFilter filter) {
this.filter = filter;
}

public void setType(Class<R> type) {
this.type = type;
}
}
Expand Up @@ -20,11 +20,15 @@
import java.util.HashSet;
import java.util.List;

import javax.xml.namespace.QName;

import com.evolveum.midpoint.prism.PrismContext;
import com.evolveum.midpoint.prism.PrismObjectDefinition;
import com.evolveum.midpoint.prism.marshaller.QueryConvertor;
import com.evolveum.midpoint.prism.query.ObjectFilter;
import com.evolveum.midpoint.prism.query.ObjectQuery;
import com.evolveum.midpoint.schema.ResultHandler;
import com.evolveum.midpoint.schema.VirtualAssignmenetSpecification;
import com.evolveum.midpoint.schema.constants.SchemaConstants;
import com.evolveum.midpoint.schema.result.OperationResult;
import com.evolveum.midpoint.util.exception.SchemaException;
Expand All @@ -33,13 +37,14 @@
import com.evolveum.midpoint.xml.ns._public.common.common_3.LifecycleStateModelType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.LifecycleStateType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.RoleType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.VirtualAssignmentSpecificationType;
import com.evolveum.prism.xml.ns._public.query_3.SearchFilterType;

/**
* @author semancik
*
*/
public class LifecyleUtil {
public class LifecycleUtil {

public static LifecycleStateType findStateDefinition(LifecycleStateModelType lifecycleStateModel, String targetLifecycleState) {
if (lifecycleStateModel == null) {
Expand All @@ -56,21 +61,41 @@ public static LifecycleStateType findStateDefinition(LifecycleStateModelType lif
return null;
}

public static ObjectFilter getForcedAssignmentFilter(LifecycleStateModelType lifecycleModel, String targetLifecycleState, PrismContext prismContext) throws SchemaException {
LifecycleStateType stateDefinition = findStateDefinition(lifecycleModel, targetLifecycleState);
public static <R extends AbstractRoleType> VirtualAssignmenetSpecification<R> getForcedAssignmentSpecification(LifecycleStateModelType lifecycleStateModel,
String targetLifecycleState, PrismContext prismContext) throws SchemaException {
LifecycleStateType stateDefinition = findStateDefinition(lifecycleStateModel, targetLifecycleState);
if (stateDefinition == null) {
return null;
}

SearchFilterType filter = stateDefinition.getForcedAssignment();
VirtualAssignmentSpecificationType virtualAssignmentSpecificationType = stateDefinition.getForcedAssignment();
if (virtualAssignmentSpecificationType == null) {
return null;
}

SearchFilterType filter = virtualAssignmentSpecificationType.getFilter();
if (filter == null) {
return null;
}

ObjectFilter objectFilter = QueryConvertor.parseFilter(filter, RoleType.class, prismContext);
return objectFilter;
QName targetType = virtualAssignmentSpecificationType.getTargetType();
Class<R> targetClass = (Class<R>) AbstractRoleType.class;
if (targetType != null) {
targetClass = (Class<R>) prismContext.getSchemaRegistry().getCompileTimeClassForObjectType(targetType);
}

VirtualAssignmenetSpecification<R> virtualAssignmenetSpecification = new VirtualAssignmenetSpecification();
virtualAssignmenetSpecification.setType(targetClass);


ObjectFilter objectFilter = QueryConvertor.parseFilter(filter, targetClass, prismContext);
virtualAssignmenetSpecification.setFilter(objectFilter);

return virtualAssignmenetSpecification;
}



// public static <T extends AbstractRoleType> Collection<T> getListOfForcedRoles(LifecycleStateModelType lifecycleModel,
// String targetLifecycleState, PrismContext prismContext, ObjectResolver resolver, Task task, OperationResult result) {
// ObjectFilter filter = getForcedAssignmentFilter(lifecycleModel, targetLifecycleState, prismContext);
Expand Down
Expand Up @@ -2031,7 +2031,7 @@
</xsd:appinfo>
</xsd:annotation>
</xsd:element>
<xsd:element name="forcedAssignment" type="q:SearchFilterType" minOccurs="0">
<xsd:element name="forcedAssignment" type="tns:VirtualAssignmentSpecificationType" minOccurs="0" maxOccurs="1">
<xsd:annotation>
<xsd:documentation>
<p>
Expand Down Expand Up @@ -2106,6 +2106,46 @@
</xsd:element>
</xsd:sequence>
</xsd:complexType>

<xsd:complexType name="VirtualAssignmentSpecificationType">
<xsd:annotation>
<xsd:documentation>
<p>
There are cases when you need to force midpoint thinks that user has assigned some
role. The assignemnt actually doesn't exist but there is a need to preted as it does.
This can be used e.g. for post-authentication flow. The user has assigned all business,
application, etc. roles but we don't want to consider these roles during his
post-authentication proces. Instead, we want to pretend he has "temporary" role assigned
which allows him to perform post-authentication.
</p>
</xsd:documentation>
<xsd:appinfo>
<a:container/>
<a:since>3.8.1</a:since>
<a:experimental>true</a:experimental>
</xsd:appinfo>
</xsd:annotation>
<xsd:sequence>
<xsd:element name="targetType" type="xsd:QName" minOccurs="0" maxOccurs="1">
<xsd:annotation>
<xsd:documentation>
<p>
The target type of the assignment, e.g RoleType, ServiceType, OrgType, ...
</p>
</xsd:documentation>
</xsd:annotation>
</xsd:element>
<xsd:element name="filter" type="q:SearchFilterType" minOccurs="0" maxOccurs="1">
<xsd:annotation>
<xsd:documentation>
<p>
No filter, no virtual assignemnts.
</p>
</xsd:documentation>
</xsd:annotation>
</xsd:element>
</xsd:sequence>
</xsd:complexType>

<xsd:complexType name="LifecycleStateTransitionType">
<xsd:annotation>
Expand Down
Expand Up @@ -345,5 +345,5 @@ public ExecuteCredentialResetResponseType executeCredentialsReset(PrismObject<Us

public void clearCaches();

void refreshPrincipal(String oid);
void refreshPrincipal(String oid) throws ObjectNotFoundException, SchemaException;
}
Expand Up @@ -1709,13 +1709,13 @@ public void clearCaches() {
}

@Override
public void refreshPrincipal(String name) {
public void refreshPrincipal(String oid) throws ObjectNotFoundException, SchemaException {
try {
MidPointPrincipal principal = userProfileService.getPrincipal(name);
MidPointPrincipal principal = userProfileService.getPrincipalByOid(oid);
securityContextManager.setupPreAuthenticatedSecurityContext(principal);
} catch (ObjectNotFoundException | SchemaException e) {
LOGGER.error("Cannot refresh authentication for user identified with" + name);
//TODO: how to handle?
LOGGER.error("Cannot refresh authentication for user identified with" + oid);
throw e;
}


Expand Down
Expand Up @@ -52,13 +52,14 @@
import com.evolveum.midpoint.prism.query.builder.QueryBuilder;
import com.evolveum.midpoint.repo.api.RepositoryService;
import com.evolveum.midpoint.schema.ResultHandler;
import com.evolveum.midpoint.schema.VirtualAssignmenetSpecification;
import com.evolveum.midpoint.schema.constants.ExpressionConstants;
import com.evolveum.midpoint.schema.constants.ObjectTypes;
import com.evolveum.midpoint.schema.constants.SchemaConstants;
import com.evolveum.midpoint.schema.internals.InternalMonitor;
import com.evolveum.midpoint.schema.result.OperationResult;
import com.evolveum.midpoint.schema.util.FocusTypeUtil;
import com.evolveum.midpoint.schema.util.LifecyleUtil;
import com.evolveum.midpoint.schema.util.LifecycleUtil;
import com.evolveum.midpoint.schema.util.ObjectResolver;
import com.evolveum.midpoint.schema.util.ObjectTypeUtil;
import com.evolveum.midpoint.security.api.Authorization;
Expand Down Expand Up @@ -330,37 +331,41 @@ private void evaluateFromSegment(AssignmentPathSegmentImpl segment, PlusMinusZer
}

boolean isVirtual = isForcedAssignment(segment, ctx);
ctx.evalAssignment.setVirtual(isVirtual);

segment.setValidityOverride(isVirtual);
boolean isValid = (evaluateContent && evaluateSegmentContent(segment, relativeMode, ctx)) || isVirtual;


ctx.assignmentPath.removeLast(segment);
if (ctx.assignmentPath.isEmpty()) { // direct assignment
ctx.evalAssignment.setValid(isValid);
ctx.evalAssignment.setVirtual(isVirtual);
}

LOGGER.info("evalAssignment isVirtual {} ", ctx.evalAssignment.isVirtual());
}

private boolean isForcedAssignment(AssignmentPathSegmentImpl segment, EvaluationContext ctx) {
private <R extends AbstractRoleType> boolean isForcedAssignment(AssignmentPathSegmentImpl segment, EvaluationContext ctx) {

F focusNew = focusOdo.getNewObject().asObjectable();
Collection<AbstractRoleType> forcedRoles = new HashSet<>();
Collection<R> forcedRoles = new HashSet<>();
try {
ObjectFilter filter = LifecyleUtil.getForcedAssignmentFilter(focusStateModel, focusNew.getLifecycleState(), prismContext);
if (filter == null) {
VirtualAssignmenetSpecification<R> virtualAssignmenetSpecification = LifecycleUtil.getForcedAssignmentSpecification(focusStateModel, focusNew.getLifecycleState(), prismContext);
if (virtualAssignmenetSpecification == null) {
return false;
}

ResultHandler<AbstractRoleType> handler = (object, result) -> {
ResultHandler<R> handler = (object, result) -> {
return forcedRoles.add(object.asObjectable());
};
objectResolver.searchIterative(AbstractRoleType.class, ObjectQuery.createObjectQuery(filter), null, handler, ctx.task, ctx.result);
objectResolver.searchIterative(virtualAssignmenetSpecification.getType(),
ObjectQuery.createObjectQuery(virtualAssignmenetSpecification.getFilter()), null, handler, ctx.task, ctx.result);
} catch (SchemaException | ObjectNotFoundException | CommunicationException | ConfigurationException
| SecurityViolationException | ExpressionEvaluationException e) {
LOGGER.error("Cannot search for forced roles", e);
}

for (AbstractRoleType forcedRole : forcedRoles) {
for (R forcedRole : forcedRoles) {
ObjectFilter filterTargetRef = QueryBuilder.queryFor(AssignmentType.class, prismContext)
.item(AssignmentType.F_TARGET_REF).ref(forcedRole.getOid()).buildFilter();
AssignmentType assignmentType = getAssignmentType(segment, ctx);
Expand Down
Expand Up @@ -467,7 +467,8 @@ public String debugDump(int indent) {
DebugUtil.debugDumpWithLabelLn(sb, "assignment new", String.valueOf(assignmentIdi.getItemNew()), indent + 1);
DebugUtil.debugDumpWithLabelLn(sb, "evaluatedOld", evaluatedOld, indent + 1);
DebugUtil.debugDumpWithLabelLn(sb, "target", String.valueOf(target), indent + 1);
DebugUtil.debugDumpWithLabel(sb, "isValid", isValid, indent + 1);
DebugUtil.debugDumpWithLabelLn(sb, "isValid", isValid, indent + 1);
DebugUtil.debugDumpWithLabel(sb, "isVirtual", virtual, indent + 1);
if (forceRecon) {
sb.append("\n");
DebugUtil.debugDumpWithLabel(sb, "forceRecon", forceRecon, indent + 1);
Expand Down
Expand Up @@ -81,6 +81,7 @@
import com.evolveum.midpoint.schema.ResourceShadowDiscriminator;
import com.evolveum.midpoint.schema.ResultHandler;
import com.evolveum.midpoint.schema.SelectorOptions;
import com.evolveum.midpoint.schema.VirtualAssignmenetSpecification;
import com.evolveum.midpoint.schema.constants.ExpressionConstants;
import com.evolveum.midpoint.schema.constants.SchemaConstants;
import com.evolveum.midpoint.schema.result.OperationResult;
Expand Down Expand Up @@ -573,21 +574,21 @@ public static boolean isAssignmentValid(FocusType focus, AssignmentType assignme
return isValid(assignmentType.getLifecycleState(), assignmentType.getActivation(), now, activationComputer, focusStateModel);
}

public static Collection<AssignmentType> getForcedAssignments(LifecycleStateModelType lifecycleModel, String targetLifecycle,
public static <R extends AbstractRoleType> Collection<AssignmentType> getForcedAssignments(LifecycleStateModelType lifecycleModel, String targetLifecycle,
ObjectResolver objectResolver, PrismContext prismContext, Task task, OperationResult result) throws SchemaException,
ObjectNotFoundException, CommunicationException, ConfigurationException, SecurityViolationException, ExpressionEvaluationException {
ObjectFilter filter = LifecyleUtil.getForcedAssignmentFilter(lifecycleModel, targetLifecycle, prismContext);
VirtualAssignmenetSpecification<R> virtualAssignmenetSpecification = LifecycleUtil.getForcedAssignmentSpecification(lifecycleModel, targetLifecycle, prismContext);

Collection<AssignmentType> forcedAssignments = new HashSet<>();
if (filter != null) {
if (virtualAssignmenetSpecification != null) {

ResultHandler<AbstractRoleType> handler = (object, parentResult) -> {
ResultHandler<R> handler = (object, parentResult) -> {
AssignmentType assignment = ObjectTypeUtil.createAssignmentTo(object);
return forcedAssignments.add(assignment);
};

objectResolver.searchIterative(AbstractRoleType.class,
ObjectQuery.createObjectQuery(filter), null, handler, task, result);
objectResolver.searchIterative(virtualAssignmenetSpecification.getType(),
ObjectQuery.createObjectQuery(virtualAssignmenetSpecification.getFilter()), null, handler, task, result);

}

Expand Down

0 comments on commit eef45f7

Please sign in to comment.