How to notify future account expiration

In my previous posts, I wrote how you can fix temporary mistakes in HR data. If you have up to date data in HR, you are a happy Identity Engineer and your customer is a happy midPoint user. Midpoint automatically creates the user from HR data, send new user’s credentials over email or SMS. Set up basic accounts in the target systems. Assign basic business roles related to organization structure, locality and work position. If an employee left your company, midpoint automatically disables it and later can delete his all accounts.

But what to do, when you have (maybe old) information when employment contract end from HR (validTo), but your employee will really continue in your company? In ideal world validTo never expires for actual employees and midPoint never disable or delete a needed accounts. But in HR personnel’s are humans, and human is not a robot. Sometimes miss something, or is not notified with employees manager to prolong contract, you know ????. To boost this process, midpoint can send email notification for example 15 days before the account will be disabled. This time can help personnel’s, managers or employees to (start and) finish paperwork on time.

Yes, I know, this is a job for HR system, not for IDM. Some HR systems already doing this job. Others have several limitations. You can send email only to one static address, not to the employee or his manager. Not 15 day before, only once a month, or only static horrible email subjects and body’s and so on. But midPoint is extremely configurable, you can do almost anything and what you can’t solve yourself, we can help you over professional services.

To configure this type of notification we create a query to find users who have validTo 15 days after today. This query put to bulk action notification task, where we specify the email message subject body, recipients. After configuring notification transport we can run this task to verify and also schedule to run every night.

Step 1: creating sample data

We need to create at least one “test” user over midPoint menu “Users” –> “New user”, fill his “Name”, “Email address” and “Activation/Valid to”:

I fill it to 2019-02-09 (without time, so 00:00) because I wrote this blog on 2019-01-24. If you try yourself, please increase current date with 16 days (or 15 days but also fill time to 23:59 PM) for testing.

Step 2: writing midPoint query

Now we need the right query to determine midpoint users where validTo will expire in 15 days. We can use Date filtering on UserType object, create and verify query over midpoint GUI in menu item “Query playground”:

We have several prepared samples at the bottom of the page (1.). The nearest what we have is “Users in cost center 100000-999999 or X100-X999”. If we choose it, “Object type” will fill up with “UserType” (2.) and in query box (3.) we see the sample query. On the picture I already updated the sample query for our needs, so you can see instead concrete <value>, <script> to calculate NOW + 15 days as start date and NOW + 16 days as the end date. If we click “Translate and execute”, midpoint translate the query to hibernate query (5). You can verify your requirements and parameter values also (6.). At the bottom of the page, you can see our “test” users as the result which meets our expectation.

Step 3: writing a bulk action notification task

Now we copy the sample from wiki, look on generalNotifier details to customize it, enable HTML body with UTF-8 charset to have freedom and skip plaintext restrictions:

<?xml version="1.0" encoding="UTF-8"?>
<task xmlns="http://midpoint.evolveum.com/xml/ns/public/common/common-3" xmlns:q="http://prism.evolveum.com/xml/ns/public/query-3"
  xmlns:c="http://midpoint.evolveum.com/xml/ns/public/common/common-3" xmlns:t="http://prism.evolveum.com/xml/ns/public/types-3"
  xmlns:org="http://midpoint.evolveum.com/xml/ns/public/common/org-3" xmlns:icfs="http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/resource-schema-3"
  xmlns:ri="http://midpoint.evolveum.com/xml/ns/public/resource/instance-3" oid="d7b0e672-c186-4e3b-8cee-89bd3261f29e">
  <name>Notify 15 days before user expire</name>
  <extension xmlns:se="http://midpoint.evolveum.com/xml/ns/public/model/scripting/extension-3" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance xsi:type="c:ExtensionType">
    <se:executeScript xmlns:s="http://midpoint.evolveum.com/xml/ns/public/model/scripting-3">
      <s:pipeline list="true">
        <s:expression xsi:type="s:SearchExpressionType">
          <s:type>UserType</s:type>
          <s:searchFilter>
            <q:and>
              <q:greater>
                 <q:path>activation/validTo</q:path>
                 <expression>
                   <script>
                     <code>
import javax.xml.datatype.DatatypeFactory;
calendar = basic.currentDateTime().toGregorianCalendar();
calendar.add(Calendar.DAY_OF_MONTH, 15);
xmldate = DatatypeFactory.newInstance().newXMLGregorianCalendar(calendar);
return xmldate; 
                     </code>
                   </script>
                 </expression>
               </q:greater>
               <q:lessOrEqual>
                 <q:path>activation/validTo</q:path>
                 <expression>
                   <script>
                     <code>
import javax.xml.datatype.DatatypeFactory;
calendar = basic.currentDateTime().toGregorianCalendar();
calendar.add(Calendar.DAY_OF_MONTH, 16);
xmldate = DatatypeFactory.newInstance().newXMLGregorianCalendar(calendar);
return xmldate; 
                     </code>
                   </script>
                 </expression>
               </q:lessOrEqual>
             </q:and>
           </s:searchFilter>
         </s:expression>
         <s:expression xsi:type="s:ActionExpressionType">
           <s:type>notify</s:type>
           <s:parameter xmlns:qn309="http://midpoint.evolveum.com/xml/ns/public/common/common-3">
             <s:name>handler</s:name>
             <value xsi:type="c:EventHandlerType">
               <generalNotifier>
                 <recipientExpression>
                   <!-- <value>hr@example.com</value> --> <!-- if you need static recipient -->
                   <script xsi:type="c:ScriptExpressionEvaluatorType">
                     <code>
import com.evolveum.midpoint.xml.ns._public.common.common_3.UserType;

user = (UserType) event.object.asObjectable();

if (!basic.isEmpty(user?.emailAddress)) {
    return user?.emailAddress;
    // here you can find his manager and return managers email address
} 

// in case when email address is empty
return 'idmadmin@example.com'; 
                     </code>
                   </script>
                 </recipientExpression>
                 <subjectExpression>
                   <value>Your account will be expired in 15 days.</value>
                 </subjectExpression>
                 <bodyExpression>
                   <script xsi:type="c:ScriptExpressionEvaluatorType">
                     <code>
import com.evolveum.midpoint.xml.ns._public.common.common_3.UserType;

user = (UserType) event.object.asObjectable();

body = '&lt;html&gt;&lt;body&gt;';
body += 'Your access for '+user.name+' will expires by 15 days. If your contract will be continued, please contact your manager to prolong access.';
body += '&lt;br/&gt;&lt;br/&gt;Your IDM system MidPoint';
body += '&lt;/body&gt;&lt;/html&gt;';

return body;
                     </code>
                   </script>
                 </bodyExpression>
                 <contentType>text/html; charset=UTF-8</contentType>
                 <transport>mail</transport>
               </generalNotifier>
             </value>
           </s:parameter>
         </s:expression>
       </s:pipeline>
    </se:executeScript>
  </extension>

  <taskIdentifier>1000000000000-0-0</taskIdentifier>
  <ownerRef oid="00000000-0000-0000-0000-000000000002" type="c:UserType"><!-- administrator --></ownerRef>
  <executionStatus>runnable</executionStatus>
  <category>BulkActions</category>
  <handlerUri>http://midpoint.evolveum.com/xml/ns/public/model/scripting/handler-3</handlerUri>
  <recurrence>recurring</recurrence>
  <binding>loose</binding>
  <schedule>
    <cronLikePattern>0 59 23 * * ?</cronLikePattern> <!-- every day at 23:59 to catch also dates with 0:00 time -->
    <misfireAction>executeImmediately</misfireAction>
  </schedule>
  <threadStopAction>restart</threadStopAction>
</task>

This task we can import over midpoint menu “Import objects” and see it under “Server tasks” –> “List tasks”.

Step 4: configuring notification transport

For demo purpose, we just redirect notifications to file, but you can also enable email or SMS notification. In midpoint menu open “System” –> “Notifications”, put “notification.log” to “Redirect to file” and click “Save”.

Step 5: run custom notification

In menu “Server tasks” –> “List tasks” click on “Notify 15 days before user expire”, at the bottom of page click “Run now”. If you have good sample users and query return it, you can see in “notification.log” file something similar to this:

============================================ 
Thu Jan 24 17:22:27 CET 2019
Message{to='[test@example.com]', cc='[]', bcc='[]', subject='Your account will be expired in 15 days.', contentType='text/html; charset=UTF-8', body='<html><body>Your acces for test will expires by 15 days. If your contract will be continued, please contact your manager to prolong access.<br/><br/>Your IDM system idPoint</body></html>'}

Step 6: schedule task to run every day automatically

In menu “Server tasks” –> “List tasks” click on “Notify 15 days before user expire”, tab “Schedule” and at the bottom of page click “Edit”. In “Schedule cron-like specification” you see “0 59 23 * * ?” – run every day this task at 23:59, for cron-like syntax you also see a link to the tutorial.

Update it if you need and click “Save”. MidPoint will start your job every day and send explained notification.

With the same principles, you can send a notification to the employee’s manager. You just need to have information in midpoint who is who’s manager. Or notification to change the password before expiration, to verify and delete old or unused accounts, roles, organizational unit and so on.

Enjoy your work and praise from the client. Every time when we say “I try to do it” instead of “I can’t do it”, “midpoint not support it” or “this is a job for another system” we working to create a better world, less human mistakes and do not forget to thank to midPoint and Evolveum by considering subscription and/or partnership.

Leave a Reply

Your email address will not be published. Required fields are marked *