Getting Started Building a SOAP Driver for IDM - Part 7

1 Likes
Starting A SOAP Driver for IDM Part 7:

Novell Identity Manager comes with a bunch of prebuilt and out of the box drivers that mostly do what is needed for most cases. However some drivers allow for so much flexibility that no out of the box configuration will ever be complete. The JDBC driver, which can connect to many different databases comes with some of the big ones (Oracle, Microsoft SQL Server) configured, but the rest are sort of up to you. Mostly because almost everyone uses databases differently. Novell has talked about a fan out configuration for the JDBC driver that will come out after the formal release of Identity Manager 4.0. That will probably manage the case of out of the box database models, like using Oracle with 'Oracle Users' in which case, you can imagine a model fairly easily where the driver could be set up to push users into many dozens of such Oracle databases that all use the same basic model of users, really differing only in host information (DB server, port, database name, etc) and using entitlements to specify which database the user gets access too.



But the SOAP driver is even harder to provide useful default configurations. Well it ships with a DSML and SPML 1.0 configuration, since those are the only really mature standards for SOAP operations involving users. But SOAP is basically as open ended as you want it to be, and everyone does whatever they want.



For example, the User Application is more about Provisioning than user events directly, but if you really wanted too, you could use the SOAP driver to talk to the User Application. (Actually, it is almost as much fun to use a Workflow, to use a SOAP integration activity, to talk to User Application to do stuff.)



With that said, there are some big targets for SOAP that you could develop configurations for. I started this series to try and provide notions on how you might do that, using Salesforce.com as the target, since it is a pretty big target to aim at. However the concepts involved would be much the same that would be used to try and target any other SOAP system. Heck I used the ideas I developed here in my SOAP integration activity in a Workflow to call User Application web services.



In part 1 of this series, Getting Started Building a SOAP Driver for IDM - Part 1 I discussed some of the things you need to get started building a SOAP driver. I was using the example of Salesforce.com (henceforth known as SFDC, since typing the full name is too much of a pain each time). In Part 1 I focused on how you might start connecting via SOAP to get a session ID.



In Part 2 of this series ( Getting Started Building a SOAP Driver for IDM - Part 2
) I discussed how you might process the results from SFDC after you submit a login request, and converting it into an <instance> document.



In Part 3 of this series Getting Started Building a SOAP Driver for IDM - Part 3 I discussed how you might handle query events and their responses.



In Part 4 of this series Getting Started Building a SOAP Driver for IDM - Part 4 I talked about some of the background stuff you need to manage, like attribute syntaxes, and left hanging two more concepts. Subscriber channel write events, like <add> or <modify> events, that need to be sent to SFDC, and the ability to get events onto the Publisher channel.



In Part 5 of this series Getting Started Building a SOAP Driver for IDM - Part 5 I started talking about how you would map add and modify events from Identity Manager into SFDC events. This would allow you to write changes (modify events) back to SFDC, or add new users to SFDC.



I started talking about how you would handle modify events, and left add events as an exercise. However I did not finish the modify discussion. I showed some sample code, to manage it, but I would like to discuss the actual process that the code sample uses.



In Part 6 of this series Getting Started Building a SOAP Driver for IDM - Part 6 I finished talking about how to handle modify events. However add events were not addressed.



I will probably not deal with add events, since I never actually did try to make it work. The Salesforce driver shipping with Identity Manager 4 in the very new future will include the functionality to create users in SFDC (<add class-name="User"> events).



I think it should be relatively straight forward. The issues I know will come up are:



1) Specifying a Profile value.

2) Passwords

3) Getting the database Id and adding an association based upon it.



The profile value is one that the shipping Novell driver has as an issue as well. There is a table in SFDC called Profile and it lists the various profile types configured in the system. This is where you specify what type of user you are making. If you use ApexExplorer you can easily read out the Profile table and figure out what you want to use for your users. You need to provide the database Id, the 18 character string when you create a new user. This is how you decide what kind of user this will be. An administrator or user. There is also an additional group like entitlement I never really looked into for additional rights, but I leave that to you the reader to figure out.



For passwords, I had not looked at it before but the good news is there is a setPassword() API call, and all you need if the username and password you want to set!



You would actually probably want to intercept this event in the Subscriber Command Transform, in the Password Policy rules.



In those rules, which you can read more about in these two articles,
Password Transformation Rule Sets
Password Transformation Rules in the Publisher Channel
you will see that in the Subscriber channel, the <modify-attr attr-name="nspmDistributionPassword"> node gets trapped, and converted into a <modify-password> event.



This means you could then have a rule in your output transform set that converts <modify-password> events into the specific SOAP event needed to do the password change, much as we have done in the past series of articles. The output SOAP document based on the WSDL would need to look something like this:



<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:urn="urn:enterprise.soap.sforce.com">
<soapenv:Header>
<urn:SessionHeader>
<urn:sessionId>SomeSessionIdValue</urn:sessionId>
</urn:SessionHeader>
</soapenv:Header>
<soapenv:Body>
<urn:setPassword>
<urn:userId>Bob@acme.com</urn:userId>
<urn:password>MyNewPassword</urn:password>
</urn:setPassword>
</soapenv:Body>
</soapenv:Envelope>



Just to make things a little more complicated there is also a resetPassword() function, that looks something like this, according to the WSDL's definitions:



<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:urn="urn:enterprise.soap.sforce.com">
<soapenv:Header>
<urn:EmailHeader>
<urn:triggerAutoResponseEmail>?</urn:triggerAutoResponseEmail>
<urn:triggerOtherEmail>?</urn:triggerOtherEmail>
<urn:triggerUserEmail>?</urn:triggerUserEmail>
</urn:EmailHeader>
<urn:SessionHeader>
<urn:sessionId>SomeSessionIdValue</urn:sessionId>
</urn:SessionHeader>
</soapenv:Header>
<soapenv:Body>
<urn:resetPassword>
<urn:userId>Bob@acme.com</urn:userId>
</urn:resetPassword>
</soapenv:Body>
</soapenv:Envelope>



This particular example you can see resets the password to some random value and sends an email to the user, so that they have to go change tier own password.



Probably this is less useful, in an IDM environment where you want to keep the passwords synchronized with other systems, instead of being different. However, depending upon your needs you seem to have some flexibility in how to handle this issue.



Now getting passwords out of SFDC on the Publisher channel? I would say for now that is not easily possible. There is no API that I saw for SFDC to report a password change event and provide the value. This is something Salesforce.com would have to add.



However, for now, it is useful to be able to push passwords to SFDC as at least a first step.



The last step that would be needed for handling an <add> event would be to get the database ID that gets generated by SFDC, to write back to the user. I happened to store this twice. Once as an attribute, lets call it acmeGAId, which is easy to search for, since I will index it in eDirectory. The second place it is used, is as the Association value. This is the string component of the DirXML-Association value that gets added to the object. DirXML-Association values use PATH syntax, a really cool eDirectory syntax type I love to overuse. You can read more about eDirectory syntax types in this series of articles:

Interesting Schema Syntaxes in eDirectory from an Identity Manager Perspective - Part 1

Interesting Schema Syntaxes in eDirectory from an Identity Manager Perspective - Part 2



Basically PATH syntax has a 32 bit integer, a DN attribute, and a String attribute. This was originally intended for referencing the file system via the directory. The integer was meant to hold the namespace (usually 0,1,2, or 3) which is bit wasteful for a 32 bit integer, and thus the components name is 'nameSpace'. The DN attribute is meant to reference the volume object by its DN and thus the component name is 'volume'. The string attribute is meant to be a string of the path inside the volume to the referenced file or directory. thus its component name is 'path'.



When used in a DirXML-Association, we use the 32 bit integer to hold the state of the association usually 0-5. (0 is ignore this object, 1 is associated, 2, 3, 4, and 5 are rarely if ever seen now, and I forget their meanings!). The DN holds the Driver object DN so that we can have an association per driver. Finally the string attribute holds the Association value itself.



You can see some of the possible Association values in this article I am maintaining:
Open Call - IDM Association Values for eDirectory Objects
If you happen to see a driver I do not have a value for yet, let me know so I can update the article. Especially if you happen to have written (or are just using) a third party driver, so I can add a link to the vendor as well.



To use XPATH to look at Association values, it is a little tricky, but once you understand it, straightforward. You can read more about how you might do that in this article:
Using XPATH to examine Association values



In order for this to work, in the Input Transform, you will need a rule that looks for <upsertResponse> events, (with a nice funky XPATH test of something like: self::soapenv:Envelope/soapenv:Body/urn:upsertResponse )



Basically this is the same as the <loginResponse> function we handled in part 2 ( Getting Started Building a SOAP Driver for IDM - Part 2) of this series, except that in this case, the <upsertResponse> will look something like this sample document:



<nds dtdversion="2.0">
<source>
<product build="20100818_191709" instance="SOAP-SPML" version="3.5.5">Identity Manager Driver for SOAP</product>
<contact>Novell, Inc.</contact>
</source>
<output>
<soapenv:Envelope xmlns="urn:enterprise.soap.sforce.com" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Body>
<upsertResponse>
<result>
<created>false</created>
<id>a0CT0000003pf9bMAA</id>
<success>true</success>
</result>
</upsertResponse>
</soapenv:Body>
</soapenv:Envelope>
</output>
</nds>




What is nice with this generic response is that it has a couple of useful hints. If you see a <created> node under the <upsertResponse> node, then you can tell if the user was modified (value of false) or add'ed (value for created of true).



Additionally you get the <id> node with the database ID value returned on every such event.



You would want to turn this into a <instance> document, much like we did in part two of this series for loginResponse documents.



Then you could either in the conversion policy, or else in a later policy, generate the <add-association> event, using the <id> data to set the association value.



You should probably also watch the <success> node and if it returns a false, generate a <status> event of either type warning or error. After all, your modify event failed.



That is probably another good idea for another article. Talking about handling error conditions and converting them to XDS <status> documents. Probably worth emailing someone when the driver's password is reported as incorrect or locked out (which happens allot when you are testing!)



With all that in mind, managing <add> events should be pretty straightforward. As always the devil is in the details, of which there are many, but nothing show stopping that I can see. I had no need to create objects in SFDC in my project where I worked on this, so I did not bother working through the details, but it looks very doable.



Next up in part 8 of this series I will try and close out most of the major functionality by talking about how you might use the getUpdated() function in the SOAP API to ask SFDC for updated objects on the Publisher channel.



As I write this, Identity Manager 4 Advanced Edition was just released, and it includes a Salesforce.com driver. Lest you think this entire series of articles was for nothing, you should realize the Novell driver is really a 1.0 release, and only supports Subscriber channel events, and cannot get events onto the Publisher channel.



My approach is to do both in this series of articles. So next article offers ideas on how you might manage Publisher channel events, and though I have not tested it, ought to be retrofitable onto the Novell Salesforce.com driver as well!



Labels:

How To-Best Practice
Comment List
Related
Recommended