[midPoint] Generation of $user/name on reconcilitation of new account
Ivan Noris
ivan.noris at evolveum.com
Mon Jun 5 17:00:25 CEST 2017
Hi Glenn,
not sure; I was using this for years after being hinted by developers. I
usually also mention it during our midPoint trainings.
Best regards,
Ivan
On 05/22/2017 10:06 AM, BOSCHMANS Glenn wrote:
>
> Hi Ivan,
>
>
>
> At first glance, the work-around does it job. Thanks for your help!
>
>
>
> Is there any documentation on ScriptExpressionEvaluationContext (and
> possibly similar classes)? A search on the wiki returned no results.
>
>
>
> Best regards,
>
> Glenn
>
>
>
> *From:*midPoint [mailto:midpoint-bounces at lists.evolveum.com] *On
> Behalf Of *Ivan Noris
> *Sent:* vrijdag 19 mei 2017 22:40
> *To:* midpoint at lists.evolveum.com
> *Subject:* Re: [midPoint] Generation of $user/name on reconcilitation
> of new account
>
>
>
> 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
> <resource:94f21f3e-89b6-4d93-8cbc-e1bfc9fa41dd%28External>
> 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 <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/20170605/fd908d14/attachment.htm>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: image001.png
Type: image/png
Size: 26659 bytes
Desc: not available
URL: <https://lists.evolveum.com/pipermail/midpoint/attachments/20170605/fd908d14/attachment.png>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: image002.png
Type: image/png
Size: 722 bytes
Desc: not available
URL: <https://lists.evolveum.com/pipermail/midpoint/attachments/20170605/fd908d14/attachment-0001.png>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: image003.png
Type: image/png
Size: 464 bytes
Desc: not available
URL: <https://lists.evolveum.com/pipermail/midpoint/attachments/20170605/fd908d14/attachment-0002.png>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: image004.jpg
Type: image/jpeg
Size: 1260 bytes
Desc: not available
URL: <https://lists.evolveum.com/pipermail/midpoint/attachments/20170605/fd908d14/attachment.jpg>
More information about the midPoint
mailing list