<resource>
...
<schemaHandling>
...
<objectType>
...
<activation>
<existence>
<outbound>
<strength>weak</strength>
<expression>
<path>$focusExists</path>
</expression>
</outbound>
</existence>
</activation>
...
</resource>
Disable instead of Delete
Description
If an account is unassigned and there is no other existing assignment for an account midPoint will de-provisionig that account. Which means that the account will be deleted. This is the default behavior. But it can be changed. Disabling the account instead of deleting is a common requirement. And this can be quite easily achieved by adjusting the activation outbound mappings.
How To Do It
This is a two-part solution. The first part of the solution is to keep the account from being deleted. Whether an account is created or deleted is determined by existence mapping in the activation part of Resource Schema Handling definition. If the existence mapping returns true then the account will be kept alive (or created if it does not exist). If the existence mapping returns false then the account will be deleted. So, the first thing is to make sure that once the account is created it will never be deleted. This is quite easy to do:
The account will be kept alive, but if the usual administrative status mapping is used then the account will maintain the same state as the user. Therefore if the user is enabled the account will still be enabled even if it is no longer assigned. And here we come to the second part of the solution. We need to adjust the mapping for administrative status to disable the account if it is no longer "legal":
<resource>
...
<schemaHandling>
...
<objectType>
...
<activation>
<administrativeStatus>
<outbound>
<strength>strong</strength>
<expression>
<script>
<code>
import com.evolveum.midpoint.xml.ns._public.common.common_3.ActivationStatusType;
if (legal) {
input;
} else {
ActivationStatusType.DISABLED;
}
</code>
</script>
</expression>
</outbound>
</administrativeStatus>
...
</resource>
That’s it.
The variable legal
is a special-purpose variable that is available in the activation mappings.
It is set to true
if the account is legal.
That means if there is a valid assignment for that account or if the account is allowed by any other policy (such as Projection Policy). The legal
variable is set to false
if there is no "habeas corpus" for that account.
I.e. the account should not be there.
What this mapping does is that it will simply pass the user’s administrative status (which is stored in the input
variable) in case that the account is legal.
But it will always set the account status to disabled if the account is not legal.
Even more
Even more complex logic can be used in activation expressions using the "shadow" implicit variable. Following code fragment will create account only after focus has been fully enabled in midPoint and never delete the account.
<existence>
<outbound>
<strength>weak</strength>
<expression>
<variable>
<name>effectiveStatus</name>
<c:path>$focus/activation/effectiveStatus</c:path>
</variable>
<c:script>
<c:code>
import com.evolveum.midpoint.xml.ns._public.common.common_3.ActivationStatusType;
focusExists && (effectiveStatus == ActivationStatusType.ENABLED || shadow != null)
</c:code>
</c:script>
</expression>
</outbound>
</existence>
Examples
There is a complete example in midPoint Integration Tests:
This example has more than just this "disable instead of delete" feature. It also has configuration to eventually delete the account after some time and also configuration to pre-create the account.