[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