Browsing all articles from September, 2010

Using XML/XSLT for Dynamic User Access Protocols

Posted Posted by Martin P in DCM4CHEE, Development     Comments No comments
Sep
24

I have a small role in the setting up of the Irish national RIS/PACS system.  I hope I provide more solutions than problems but I’m sure that could be debated.  One of the questions that has appeared is of a category that appears in the implementation of pretty much any clinical system:  Can access to (some entity) be restricted by (some data element/property).  An example of this might be:

Can access be limited to the originating institution  for 24 hours after data generation?

The stock developer’s answer, is of course:

Yes.  But.  You have to define that element/property in advance and we can schedule it into a future release, based on available development time.

.. which isn’t terribly helpful.

Implementing a user-accessible scripting language into the system is one way of providing such a feature dynamically.  But its a tough job to retro-fit a scripting language into a system if the system was not originally designed with that in mind.  There may be another way – using data transformation.

XSLT is an XML-based language which provides transformation services for XML-based datasets.  So a dataset, when expressed in XML, can be transformed into some other representation – say HTML.  Importantly, the transformed dataset may contain some subset of the original data, but need not. It could equally be a dataset that is driven by the contents of the original dataset, but actually contain none of it.

The DCM4CHEE archive uses this idea, for example in defining forwarding rules based on the contents of DICOM fields in incoming images.  It applies an XSLT template such that, based on some set of criteria within the DICOM headers, the output is (in XML form), a parameterised list of destinations to which that image should be forwarded.

So how can this be used as a User Access Protocol?  Easy.  For each data item which is to be subject to User Access Control, package up its own element values, and element values from the wider context which are relevant, as an XML stream.  Run that through an XSLT parser with an output that defines what access the current user has.

So, for example, the dataset for an ‘order’ object may include, from its own data fields as well as wider context, the following data:

<?xml version=”1.0″ encoding=”UTF-8″?>
<?xml-stylesheet type=”text/xsl” href=”Order-Access.xsl”?>
<order>
<attr tag=”procedure”>CT Head</attr>
<attr tag=”orderplacer”>Jane Doe</attr>
<attr tag=”orderinstitution”>St Elsewhere</attr>
<attr tag=”placeddatetime”>2010-09-23T12:30-04:10</attr>
<attr tag=”hours-since-order”>23</attr>
<attr tag=”currentuser”>mpeacock</attr>
<attr tag=”userinstitution”>not St Elsewhere</attr>
</order>

.. that can be processed via XSLT:

<?xml version=”1.0″ encoding=”UTF-8″?>
<xsl:stylesheet xmlns:xsl=”http://www.w3.org/1999/XSL/Transform” version=”1.0″>
<xsl:output method=”xml” indent=”no”/>
<xsl:template match=”/order”>
<xsl:variable name=”orderinstitution” select=”attr[@tag='orderinstitution']“/>
<xsl:variable name=”userinstitution” select=”attr[@tag='userinstitution']“/>
<xsl:variable name=”hours-since-order” select=”attr[@tag='hours-since-order']“/>
<access>
<xsl:choose>
<xsl:when test=”$hours-since-order > 24″>
<read>True</read>
<write>True</write>
<delete>True</delete>
</xsl:when>
<xsl:otherwise>
<xsl:if test=”$userinstitution=$orderinstitution”>
<read>True</read>
<write>True</write>
<delete>True</delete>
</xsl:if>
<xsl:if test=”$userinstitution!=$orderinstitution”>
<read>False</read>
<write>False</write>
<delete>False</delete>
</xsl:if>
</xsl:otherwise>
</xsl:choose>
</access>
</xsl:template>
</xsl:stylesheet>

…to form output XML, based on :

<?xml version=”1.0″ encoding=”UTF-8″?>
<access>
<read>True</read>
<write>True</write>
<delete>False</delete>
</access>

So in this case, we can dynamically define quite complex access rules to restrict access to an order to the originating institution only, for the first 24 hours of its lifespan. Cool.

Note there is a bit of a kludge in the XML-packaged dataset.  I’ve put in a derived field (hours-since-order) which in itself requires some pre-casting of requirements.  The main reason is that, since I’ve used DCM4CHEE as an example, DCM4CHEE straight out of the box, is limited (by virtue of JBOSS, itself by virtue of Apache XALAN) to XSLT version 1.  The really useful date-processing functions are, alas, defined in XSLT version 2.  So the next logical stage I guess is to work out how to upgrade!