[midPoint] Generation of $user/name on reconcilitation of new account
Ivan Noris
ivan.noris at evolveum.com
Fri May 19 22:39:59 CEST 2017
Hi Glenn,
the configuration looks ok to me. Or at least, I'd do it in the same
way. The configuration of iteration token expression is probably
missing, but maybe the defaults are fine.
The configuration of resource and its relationship to your object
template is OK. #addFocus action is OK (#addUser is the same, ast least
fow now, but it's deprecated and kept for backward compatibility reasons
only)
The trick and workaround follows.
The problem is with the old value of the attributes (mainly givenName,
as it's used in substring). To see that, I used <trace>true</trace>
element in the mapping:
<mapping>
<name>JIT Username generation</name>
<strength>weak</strength>
<trace>true</trace>
<source>
<c:path>$user/givenName</c:path>
</source>
<source>
<c:path>$user/familyName</c:path>
</source>
<expression>
<script>
<code>
boolean isNew =
com.evolveum.midpoint.model.common.expression.script.ScriptExpressionEvaluationContext.getThreadLocal().isEvaluateNew()
if (isNew) return
basic.norm(basic.stringify(givenName)).substring(0,1) +
basic.norm(basic.stringify(familyName)) //+ iterationToken
</code>
</script>
</expression>
<target>
<c:path>name</c:path>
</target>
</mapping>
2017-05-19 22:20:19,027 [] [midPointScheduler_Worker-6] INFO
(com.evolveum.midpoint.model.common.mapping.Mapping): Mapping trace:
---[ MAPPING 'JIT Username generation' in
objectTemplate:a2fefde3-d6e6-49eb-ae2e-586eca3d747a(Boschmans User
Template)]---------------------------
Source: *givenName: old=null*, delta=PropertyDelta( /
{.../common/common-3}givenName, ADD),
new=PP({.../common/common-3}givenName):[PPV(PolyString:Bill X.)]
Source: *familyName: old=null*, delta=PropertyDelta( /
{.../common/common-3}familyName, ADD),
new=PP({.../common/common-3}familyName):[PPV(PolyString:Gates)]
Target: PPD:{.../common/common-3}name
{http://prism.evolveum.com/xml/ns/public/types-3}PolyStringType[0,1],RAM
Expression: script: ScriptExpression( boolean isNew =
com.evolveum.midpoint.mod...)
Condition: true -> true
Result: added: bgates
As you can see, the old values are empty, but the new have correct values.
Of course I (you) could use
"basic.stringify(givenName))*?.*substring(0,1)" to avoid calling
substring on null object; but the initial would be missing then.
The above is traced after I fixed the mapping (I removed iterationToken
though), so it produced correct login (bgates for Bill X. Gates). The
workaround is to use the "isNew" condition, which evaluates to true if
the expression in the mapping is processed for the new value (and not
the old).
I still need to understand if this workaround is the only way, or if you
encountered a bug (or missing documentation which is also a bug). I
remember, several years ago I used the same principle in one of my
projects as you and it worked.
I have just finished our MidPoint Customization and Deployment training
course so I can't guarantee I have time to look at this in the couple of
following (work) days. But I'm curious to find the better
solution/answers. Until that, please try if the proposed workaround
works for you. Thank you.
Best regards,
Ivan
On 05/16/2017 04:50 PM, BOSCHMANS Glenn wrote:
>
> Hi all,
>
>
>
> Thanks for the information, but sadly still no luck. All I end up with
> is a shadow with a partial result that is in status fatal_error. I
> found this in the logs.
>
>
>
> 2017-05-16 15:40:04,072 [] [midPointScheduler_Worker-3] ERROR
> (com.evolveum.midpoint.model.impl.util.AbstractSearchIterativeResultHandler):
> Reconciliation of object
> shadow:7a70d0e8-839f-473b-ade6-ce38c91f7895(62f64fd8-4807-4a3c-8c32-129d8df890d1)
> from resource:94f21f3e-89b6-4d93-8cbc-e1bfc9fa41dd(External Database
> Userstore) failed: java.lang.StringIndexOutOfBoundsException: String
> index out of range: 1 expression in mapping 'JIT Username generation'
> in objectTemplate:52f4ca67-2bea-4da9-b26b-bffbd852fa39(JIT Username
> generation)(givenName=null; familyName=null; ) in expression in
> mapping 'JIT Username generation' in
> objectTemplate:52f4ca67-2bea-4da9-b26b-bffbd852fa39(JIT Username
> generation)
>
>
>
> So givenName and familyName are passed as null to the objectTemplate,
> but I don’t know why null is passed as those attributes have values in
> the database. I’ve probably forgotten to configure something, but I
> don’t know what it could be.
>
>
>
>
>
> Here is a part of the schema handling on the resource. I left out the
> attributes that have nothing to do with the username.
>
> <schemaHandling>
>
> <objectType>
>
> <kind>account</kind>
>
> <intent>default</intent>
>
> <default>true</default>
>
> <objectClass>ri:Account</objectClass>
>
> <attribute>
>
> <c:ref>icfs:uid</c:ref>
>
> <displayName>UID</displayName>
>
> <tolerant>true</tolerant>
>
> <exclusiveStrong>false</exclusiveStrong>
>
> </attribute>
>
> <attribute>
>
> <c:ref>icfs:name</c:ref>
>
> <tolerant>true</tolerant>
>
> <exclusiveStrong>false</exclusiveStrong>
>
> <outbound>
>
> <authoritative>true</authoritative>
>
> <exclusive>false</exclusive>
>
> <strength>normal</strength>
>
> <source>
>
> <c:path>$user/name</c:path>
>
> </source>
>
> </outbound>
>
> </attribute>
>
> <attribute>
>
> <c:ref>ri:accountUsername</c:ref>
>
> <tolerant>true</tolerant>
>
> <exclusiveStrong>false</exclusiveStrong>
>
> <outbound>
>
> <authoritative>true</authoritative>
>
> <exclusive>false</exclusive>
>
> <strength>normal</strength>
>
> <source>
>
> <c:path>$user/name</c:path>
>
> </source>
>
> </outbound>
>
> </attribute>
>
> <attribute>
>
> <c:ref>ri:accountFirstName</c:ref>
>
> <tolerant>true</tolerant>
>
> <exclusiveStrong>false</exclusiveStrong>
>
> <outbound>
>
> <authoritative>true</authoritative>
>
> <exclusive>false</exclusive>
>
> <strength>normal</strength>
>
> <source>
>
> <c:path>$user/givenName</c:path>
>
> </source>
>
> </outbound>
>
> <inbound>
>
> <authoritative>true</authoritative>
>
> <exclusive>false</exclusive>
>
> <strength>normal</strength>
>
> <target>
>
> <c:path>$user/givenName</c:path>
>
> </target>
>
> </inbound>
>
> </attribute>
>
> <attribute>
>
> <c:ref>ri:accountLastName</c:ref>
>
> <tolerant>true</tolerant>
>
> <exclusiveStrong>false</exclusiveStrong>
>
> <outbound>
>
> <authoritative>true</authoritative>
>
> <exclusive>false</exclusive>
>
> <strength>normal</strength>
>
> <source>
>
> <c:path>$user/familyName</c:path>
>
> </source>
>
> </outbound>
>
> <inbound>
>
> <authoritative>true</authoritative>
>
> <exclusive>false</exclusive>
>
> <strength>normal</strength>
>
> <target>
>
> <c:path>$user/familyName</c:path>
>
> </target>
>
> </inbound>
>
> </attribute>
>
>
>
> <credentials>
>
> <password>
>
> <outbound>
>
> <authoritative>true</authoritative>
>
> <exclusive>false</exclusive>
>
> <strength>normal</strength>
>
> </outbound>
>
> </password>
>
> </credentials>
>
> </objectType>
>
> </schemaHandling>
>
>
>
>
>
> Here is a part of the synchronization (only unmatched):
>
>
>
> <synchronization>
>
> <objectSynchronization>
>
> <name>Sync External DB Userstore</name>
>
> <kind>account</kind>
>
> <intent>default</intent>
>
> <focusType>c:UserType</focusType>
>
> <enabled>true</enabled>
>
> <reconcile>true</reconcile>
>
>
>
> <reaction>
>
> <situation>unmatched</situation>
>
> <objectTemplateRef
> oid="52f4ca67-2bea-4da9-b26b-bffbd852fa39" type="c:ObjectTemplateType">
>
> <targetName>
>
> <t:orig>JIT Username generation</t:orig>
>
> <t:norm>jit username generation</t:norm>
>
> </targetName>
>
> </objectTemplateRef>
>
> <action>
>
>
> <handlerUri>http://midpoint.evolveum.com/xml/ns/public/model/action-3#addFocus</handlerUri>
>
> </action>
>
> </reaction>
>
> </objectSynchronization>
>
> </synchronization>
>
>
>
>
>
> And finally the mapping in the objectTemplate:
>
>
>
> <mapping>
>
> <name>JIT Username generation</name>
>
> <strength>weak</strength>
>
> <source>
>
> <c:path>$user/givenName</c:path>
>
> </source>
>
> <source>
>
> <c:path>$user/familyName</c:path>
>
> </source>
>
> <expression>
>
> <script>
>
> <code>
>
> return
> basic.norm(basic.stringify(givenName)).substring(0,1) +
> basic.norm(basic.stringify(familyName))+ iterationToken
>
> </code>
>
> </script>
>
> </expression>
>
> <target>
>
> <c:path>name</c:path>
>
> </target>
>
> </mapping>
>
>
>
>
>
>
>
>
>
> *From:*midPoint [mailto:midpoint-bounces at lists.evolveum.com] *On
> Behalf Of *Ivan Noris
> *Sent:* maandag 15 mei 2017 20:33
> *To:* midPoint General Discussion
> *Subject:* Re: [midPoint] Generation of $user/name on reconcilitation
> of new account
>
>
>
> Hi Glenn,
>
>
>
> the trick with object template from Roman and Gustav is one (probably
> best) possibility.
>
>
>
> I can imagine also something like this (not tested, but should work):
>
>
>
> <attribute>
> <ref>icfs:name</ref>
> <inbound>
>
> <source>
>
> <path>$account/accountUsername</path>
>
> </source>
>
> <source>
>
> <path>$account/accountFirstname</path>
>
> </source>
>
> <source>
>
> <path>$account/accountLastname</path>
>
> </source>
> <expression>
> <script>
> <code>
>
> if (!basic.isEmpty(accountUsername)) {
>
> return accountUsername // return accountUsername if it's not null
>
> } else {
>
> return accountFirstname + '.' + accountLastname // do whatever you
> need here
>
> }
>
> </code>
> </script>
> </expression>
> <target>
> <path>$user/name</path>
> </target>
> </inbound>
>
> </attribute>
>
>
>
> The mapping is inbound for icfs:name, because for normal connector,
> that attribute will always exist.
>
> I don't know if you already have some inbound for that attribute, but
> you can have several (more than 1) inbounds for the same attribute.
>
> The question is if the mapping should also change the existing
> username in midPoint, if not, the mapping should be weak.
>
>
>
> Please note that this solution will *not* generate unique username in
> midPoint. For that you must use object template with iterators [1].
>
>
>
> [1] https://wiki.evolveum.com/display/midPoint/Unique+midPoint+User+Name
>
>
>
> Regards,
>
> Ivan
>
>
>
> ------------------------------------------------------------------------
>
> *From: *"BOSCHMANS Glenn" <gboschmans at cibg.brussels
> <mailto:gboschmans at cibg.brussels>>
> *To: *midpoint at lists.evolveum.com <mailto:midpoint at lists.evolveum.com>
> *Sent: *Monday, May 15, 2017 4:36:26 PM
> *Subject: *[midPoint] Generation of $user/name on reconcilitation
> of new account
>
>
>
> Hi all,
>
>
>
> We are creating a new environment in which midPoint will be used
> as IDM and WSO2 IS as IdP. When a user registers in the IdP
> (through Just In Time-provisioning with a federated IdP) this will
> be based on their eID. A username is not created, and thus not
> stored in the database userstore.
>
> The next step is to add those users in midPoint. We planned on
> doing reconciliation during live synchronization. However, as the
> username is null in the database, we don’t have a value for the
> $user/name attribute and so the creation of the new user fails.
>
>
>
> Is there a possibility in the schema handling to configure the
> first name and last name to generate a username? For example:
>
> accountFirstName: Glenn
>
> accountLastName: Boschmans
>
>
>
> -> $user/name: gboschmans
>
>
>
> I thought about using a Groovy script in the inbound of
> accountUsername to see if the attribute accountUsername is null.
> If not null return the value of the accountUsername attribute. If
> it is null, then I want to generate the username based on
> attributes accountFirstName and accountLastName. However, I’m not
> sure if it is possible to get the values of attributes
> accountFirstName and accountLastName.
>
>
>
> Any ideas?
>
>
>
> Thanks in advance!
>
>
>
> Best regards,
>
> Glenn Boschmans
>
>
>
> *Glenn Boschmans*
> Consultant
> Business Integrated Solutions
> Kunstlaan 21, 1000 Brussel - cibg.brussels <http://cibg.brussels>
> - disclaimer <http://cibg.brussels/disclaimer-1>
> +32 2 282 47 70 |
> Be green, leave it on the screen
> !
> <http://www.linkedin.com/company/cirb_cibg> <https://twitter.com/CIRB_CIBG> <http://www.leefmilieu.brussels/themas/duurzame-stad/label-ecodynamische-onderneming>
>
>
> _______________________________________________
> midPoint mailing list
> midPoint at lists.evolveum.com <mailto:midPoint at lists.evolveum.com>
> http://lists.evolveum.com/mailman/listinfo/midpoint
>
>
>
>
>
> --
>
> Ivan Noris
> Senior Identity Engineer
> evolveum.com
>
>
>
> _______________________________________________
> midPoint mailing list
> midPoint at lists.evolveum.com
> http://lists.evolveum.com/mailman/listinfo/midpoint
--
Ivan Noris
Senior Identity Engineer
evolveum.com
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.evolveum.com/pipermail/midpoint/attachments/20170519/abc10096/attachment.htm>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: image002.png
Type: image/png
Size: 26659 bytes
Desc: not available
URL: <https://lists.evolveum.com/pipermail/midpoint/attachments/20170519/abc10096/attachment.png>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: image003.png
Type: image/png
Size: 722 bytes
Desc: not available
URL: <https://lists.evolveum.com/pipermail/midpoint/attachments/20170519/abc10096/attachment-0001.png>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: image004.png
Type: image/png
Size: 464 bytes
Desc: not available
URL: <https://lists.evolveum.com/pipermail/midpoint/attachments/20170519/abc10096/attachment-0002.png>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: image005.jpg
Type: image/jpeg
Size: 1260 bytes
Desc: not available
URL: <https://lists.evolveum.com/pipermail/midpoint/attachments/20170519/abc10096/attachment.jpg>
More information about the midPoint
mailing list