<?xml version="1.0" encoding="UTF-8"?><rss xmlns:i18n="http://apache.org/cocoon/i18n/2.1" xmlns:p="http://outerx.org/daisy/1.0#publisher" xmlns:d="http://outerx.org/daisy/1.0" version="2.0"><channel><title>Wiki</title><link>http://cocoondev.org/wiki</link><description>A wiki for Daisy users.</description><item><title>Workflow features</title><link>http://cocoondev.org/wiki/613-cd</link><description>&lt;html&gt;
&lt;head&gt;
&lt;META http-equiv="Content-Type" content="text/html; charset=UTF-8"&gt;
&lt;base href="http://cocoondev.org"&gt;
&lt;link href="/resources/skins/default/css/daisy.css" type="text/css" rel="stylesheet"&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;div id="diff"&gt;
&lt;div&gt;
&lt;a onclick="document.getElementById('diff').style.display = 'none'; document.getElementById('document').style.display = ''; return false;" href="#"&gt;Show document&lt;/a&gt;
&lt;/div&gt;
&lt;h2&gt;General&lt;/h2&gt;
&lt;table class="default"&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;&lt;th&gt;Version 5&lt;/th&gt;&lt;th&gt;Version 4&lt;/th&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Variant&lt;/td&gt;&lt;td&gt;main - en&lt;/td&gt;&lt;td&gt;main - en&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Document Name&lt;/td&gt;&lt;td&gt;Workflow features&lt;/td&gt;&lt;td&gt;Workflow features&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Creation time&lt;/td&gt;&lt;td&gt;12/3/08 8:56:35 AM&lt;/td&gt;&lt;td&gt;11/5/08 9:32:31 AM&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Created by&lt;/td&gt;&lt;td&gt;Karel Vervaeke&lt;/td&gt;&lt;td&gt;Karel Vervaeke&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;State:&lt;/td&gt;&lt;td&gt;publish&lt;/td&gt;&lt;td&gt;publish&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;h2&gt;Changes to parts&lt;/h2&gt;
&lt;h3&gt;Part "Content" has changed&lt;/h3&gt;
&lt;br&gt;
&lt;table class="default"&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;&lt;th&gt;Version 5&lt;/th&gt;&lt;th&gt;Version 4&lt;/th&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Mime type&lt;/td&gt;&lt;td&gt;text/xml&lt;/td&gt;&lt;td&gt;text/xml&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;File name&lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Size (bytes)&lt;/td&gt;&lt;td&gt;2865&lt;/td&gt;&lt;td&gt;2746&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;br&gt;
&lt;div class="diffpage-contentdiff-title"&gt;Content changes&lt;/div&gt;
&lt;div class="diffpage-contentdiff"&gt;
&lt;div class="diff-unchanged"&gt;&amp;lt;html&amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;lt;body&amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;lt;h3&amp;gt;Status updates&amp;lt;/h3&amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;lt;ul&amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;lt;li&amp;gt;Branch created here:&lt;/div&gt;
&lt;div class="diff-removed"&gt;http://svn.cocoondev.org/viewsvn/branches/&lt;span class="diff-removed"&gt;&amp;lt;del&amp;gt;&lt;/span&gt;BRANCH_WORKFLOW_MULTIVALUE&lt;span class="diff-removed"&gt;&amp;lt;/del&amp;gt;/&lt;/span&gt;
&lt;/div&gt;
&lt;div class="diff-removed"&gt;(based on trunk rev 4792)&lt;span class="diff-removed"&gt;.&lt;/span&gt;&amp;lt;/li&amp;gt;&lt;/div&gt;
&lt;div class="diff-removed"&gt;
&lt;span class="diff-removed"&gt;&amp;lt;/ul&amp;gt;&lt;/span&gt;
&lt;/div&gt;
&lt;div class="diff-removed"&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class="diff-removed"&gt;
&lt;span class="diff-removed"&gt;&amp;lt;blockquote&amp;gt;&lt;/span&gt;
&lt;/div&gt;
&lt;div class="diff-removed"&gt;
&lt;span class="diff-removed"&gt;&amp;lt;p class="note"&amp;gt;the branch was later renamed to BRANCH_2_3_RC1&amp;lt;/p&amp;gt;&lt;/span&gt;
&lt;/div&gt;
&lt;div class="diff-removed"&gt;
&lt;span class="diff-removed"&gt;&amp;lt;/blockquote&amp;gt;&lt;/span&gt;
&lt;/div&gt;
&lt;div class="diff-removed"&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class="diff-removed"&gt;
&lt;span class="diff-removed"&gt;&amp;lt;ul&amp;gt;&lt;/span&gt;
&lt;/div&gt;
&lt;div class="diff-added"&gt;http://svn.cocoondev.org/viewsvn/branches/BRANCH_WORKFLOW_MULTIVALUE&lt;span class="diff-added"&gt;/&lt;/span&gt; (based on&lt;/div&gt;
&lt;div class="diff-added"&gt;trunk rev 4792)&amp;lt;/li&amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;lt;li&amp;gt;First iteration checked in: multi-value string variables can be persisted&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;and loaded.&amp;nbsp; The wiki correctly renders multi-value string fields.&amp;lt;/li&amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;lt;/ul&amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;lt;h3&amp;gt;Next steps&amp;lt;/h3&amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;lt;ul&amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;lt;li&amp;gt;Querying&amp;lt;/li&amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;lt;li&amp;gt;Allow other datatypes than "string" be multi-valued&amp;lt;/li&amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;lt;/ul&amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;lt;h2&amp;gt;Multi-valued variables&amp;lt;/h2&amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;lt;p&amp;gt;Currently, the concept of multi-value variables only exists in Daisy document&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;fields.&amp;nbsp; We would like to enhance the Daisy's workflow component with the same&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;feature&amp;lt;/p&amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;lt;p&amp;gt;Suggested daisy-process-meta.xml syntax:&amp;lt;/p&amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;lt;pre&amp;gt;&amp;amp;lt;workflowMeta xmlns="http://outerx.org/daisy/1.0#workflowmeta"&amp;amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;nbsp;...&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;nbsp; &amp;amp;lt;variables&amp;amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;amp;lt;variable name="my-mv-string" type="string" multiValue="true" scope="..."/&amp;amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;nbsp; &amp;amp;lt;/variables&amp;amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;nbsp; ...&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;amp;lt;/workflowMeta&amp;amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;lt;strong&amp;gt;(alternative:)&amp;lt;/strong&amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt; &amp;nbsp;&amp;nbsp; &amp;amp;lt;variable name="my-mv-string" type="multi-string" scope="..."/&amp;amp;gt;&amp;lt;/pre&amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;lt;p&amp;gt;Suggested task-update api usage:&amp;lt;/p&amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;lt;pre&amp;gt;// No api change needed here: TaskupdateData.setVariable(String name, Object value) -&amp;amp;gt; just let the value be an array&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;taskUpdateData.setVariable("my-mv-string", new String[] { "foo", "bar" });&amp;lt;/pre&amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;lt;p&amp;gt;In taskupdate.xml this would become:&amp;lt;/p&amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;lt;pre&amp;gt;&amp;lt;strong&amp;gt;alternative 1:&amp;lt;/strong&amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;amp;lt;variable name="my-mv-string" multiValue="true"&amp;amp;gt; // needed to specify to distinct between a string and a multi-value-string variable with one element&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;nbsp; &amp;amp;lt;string&amp;amp;gt;foo&amp;amp;lt;/string&amp;amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;nbsp; &amp;amp;lt;string&amp;amp;gt;bar&amp;amp;lt;/string&amp;amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;amp;lt;/variable&amp;amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;lt;strong&amp;gt;alternative 2:&amp;lt;/strong&amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;amp;lt;variable name="my-mv-string"&amp;amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;nbsp; &amp;amp;lt;multi&amp;amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;amp;lt;string&amp;amp;gt;foo&amp;amp;lt;/string&amp;amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;amp;lt;string&amp;amp;gt;bar&amp;amp;lt;/string&amp;amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;nbsp; &amp;amp;lt;/multi&amp;amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;amp;lt;/variable&amp;amp;gt;&amp;lt;/pre&amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;lt;p&amp;gt;Work involved:&amp;lt;/p&amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;lt;ul&amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;lt;li&amp;gt;repository&amp;lt;/li&amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;lt;ul&amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;lt;li&amp;gt;persistence: hibernate fields&amp;lt;/li&amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;lt;/ul&amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;lt;ul&amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;lt;li&amp;gt;querying:&amp;lt;/li&amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;lt;ul&amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;lt;li&amp;gt;Support querying multivalue fields&amp;lt;/li&amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;lt;li&amp;gt;possibly: new operators: hasAll, hasNone, hasExactly, hasAny&amp;lt;/li&amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;lt;/ul&amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;lt;/ul&amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;lt;/ul&amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;lt;ul&amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;lt;li&amp;gt;wiki&amp;lt;/li&amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;lt;ul&amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;lt;li&amp;gt;cforms styling for the multivalue fields&amp;lt;/li&amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;lt;/ul&amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;lt;/ul&amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;lt;h2&amp;gt;Custom form templates&amp;lt;/h2&amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;lt;p&amp;gt;On the wiki, allow workflow developers to customize way the forms are&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;rendered on the wiki.&amp;lt;br/&amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;This would be done by adding a custom wftask_to_cform_template.xsl to the&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;wiki-data dir, which will override the built-in one.&amp;lt;/p&amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;lt;h2&amp;gt;Disable "reassign" task&amp;lt;/h2&amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;lt;p&amp;gt;Currently it is always possible to reassign a task to someone else.&amp;nbsp; There&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;should be a possibility to disable this feature.&amp;lt;br/&amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;Suggested syntax:&amp;lt;br/&amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;(in daisy-process-meta.xml)&amp;lt;/p&amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;lt;pre&amp;gt;&amp;amp;lt;options allowReassign="false"/&amp;amp;gt;&amp;lt;/pre&amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;lt;/body&amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;lt;/html&amp;gt;&lt;/div&gt;
&lt;/div&gt;
&lt;h2&gt;Changes to links&lt;/h2&gt;
&lt;span class="diffpage-nochanges"&gt;No changes detected&lt;/span&gt;
&lt;h2&gt;Changes to fields&lt;/h2&gt;
&lt;span class="diffpage-nochanges"&gt;No changes detected&lt;/span&gt;
&lt;/div&gt;
&lt;div style="display:none" id="document"&gt;
&lt;div&gt;
&lt;a onclick="document.getElementById('diff').style.display = ''; document.getElementById('document').style.display = 'none'; return false;" href="#"&gt;Show diff&lt;/a&gt;
&lt;/div&gt;
&lt;h1 xmlns:d="http://outerx.org/daisy/1.0" xmlns:lt="http://outerx.org/daisy/1.0#linktransformer" xmlns:einclude="http://outerx.org/daisy/1.0#externalinclude" xmlns:p="http://outerx.org/daisy/1.0#publisher" xmlns:i18n="http://apache.org/cocoon/i18n/2.1" xmlns:urlencoder="xalan://java.net.URLEncoder" id="dsy613-cd" class="daisy-document-name"&gt;Workflow features&lt;/h1&gt;


&lt;h3 xmlns:jx="http://apache.org/cocoon/templates/jx/1.0" xmlns:ns="http://outerx.org/daisy/1.0"&gt;Status updates&lt;/h3&gt;


&lt;ul&gt;

&lt;li&gt;Branch created here:
http://svn.cocoondev.org/viewsvn/branches/&lt;del&gt;BRANCH_WORKFLOW_MULTIVALUE&lt;/del&gt;/
(based on trunk rev 4792).&lt;/li&gt;

&lt;/ul&gt;


&lt;blockquote&gt;

&lt;p class="note"&gt;the branch was later renamed to BRANCH_2_3_RC1&lt;/p&gt;

&lt;/blockquote&gt;


&lt;ul&gt;

&lt;li&gt;First iteration checked in: multi-value string variables can be persisted
and loaded.&amp;nbsp; The wiki correctly renders multi-value string fields.&lt;/li&gt;

&lt;/ul&gt;


&lt;h3&gt;Next steps&lt;/h3&gt;


&lt;ul&gt;

&lt;li&gt;Querying&lt;/li&gt;

&lt;li&gt;Allow other datatypes than "string" be multi-valued&lt;/li&gt;

&lt;/ul&gt;


&lt;h2&gt;Multi-valued variables&lt;/h2&gt;


&lt;p&gt;Currently, the concept of multi-value variables only exists in Daisy document
fields.&amp;nbsp; We would like to enhance the Daisy's workflow component with the same
feature&lt;/p&gt;


&lt;p&gt;Suggested daisy-process-meta.xml syntax:&lt;/p&gt;


&lt;pre&gt;&amp;lt;workflowMeta xmlns="http://outerx.org/daisy/1.0#workflowmeta"&amp;gt;
&amp;nbsp;...
&amp;nbsp; &amp;lt;variables&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;variable name="my-mv-string" type="string" multiValue="true" scope="..."/&amp;gt;
&amp;nbsp; &amp;lt;/variables&amp;gt;
&amp;nbsp; ...
&amp;lt;/workflowMeta&amp;gt;

&lt;strong&gt;(alternative:)&lt;/strong&gt;
 &amp;nbsp;&amp;nbsp; &amp;lt;variable name="my-mv-string" type="multi-string" scope="..."/&amp;gt;&lt;/pre&gt;


&lt;p&gt;Suggested task-update api usage:&lt;/p&gt;


&lt;pre&gt;// No api change needed here: TaskupdateData.setVariable(String name, Object value) -&amp;gt; just let the value be an array
taskUpdateData.setVariable("my-mv-string", new String[] { "foo", "bar" });&lt;/pre&gt;


&lt;p&gt;In taskupdate.xml this would become:&lt;/p&gt;


&lt;pre&gt;
&lt;strong&gt;alternative 1:&lt;/strong&gt;
&amp;lt;variable name="my-mv-string" multiValue="true"&amp;gt; // needed to specify to distinct between a string and a multi-value-string variable with one element
&amp;nbsp; &amp;lt;string&amp;gt;foo&amp;lt;/string&amp;gt;
&amp;nbsp; &amp;lt;string&amp;gt;bar&amp;lt;/string&amp;gt;
&amp;lt;/variable&amp;gt;

&lt;strong&gt;alternative 2:&lt;/strong&gt;
&amp;lt;variable name="my-mv-string"&amp;gt;
&amp;nbsp; &amp;lt;multi&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;string&amp;gt;foo&amp;lt;/string&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;string&amp;gt;bar&amp;lt;/string&amp;gt;
&amp;nbsp; &amp;lt;/multi&amp;gt;
&amp;lt;/variable&amp;gt;&lt;/pre&gt;


&lt;p&gt;Work involved:&lt;/p&gt;


&lt;ul&gt;

&lt;li&gt;repository&lt;/li&gt;

&lt;ul&gt;

&lt;li&gt;persistence: hibernate fields&lt;/li&gt;

&lt;/ul&gt;


&lt;ul&gt;

&lt;li&gt;querying:&lt;/li&gt;

&lt;ul&gt;

&lt;li&gt;Support querying multivalue fields&lt;/li&gt;

&lt;li&gt;possibly: new operators: hasAll, hasNone, hasExactly, hasAny&lt;/li&gt;

&lt;/ul&gt;


&lt;/ul&gt;


&lt;/ul&gt;


&lt;ul&gt;

&lt;li&gt;wiki&lt;/li&gt;

&lt;ul&gt;

&lt;li&gt;cforms styling for the multivalue fields&lt;/li&gt;

&lt;/ul&gt;


&lt;/ul&gt;


&lt;h2&gt;Custom form templates&lt;/h2&gt;


&lt;p&gt;On the wiki, allow workflow developers to customize way the forms are
rendered on the wiki.&lt;br&gt;
This would be done by adding a custom wftask_to_cform_template.xsl to the
wiki-data dir, which will override the built-in one.&lt;/p&gt;


&lt;h2&gt;Disable "reassign" task&lt;/h2&gt;


&lt;p&gt;Currently it is always possible to reassign a task to someone else.&amp;nbsp; There
should be a possibility to disable this feature.&lt;br&gt;
Suggested syntax:&lt;br&gt;
(in daisy-process-meta.xml)&lt;/p&gt;


&lt;pre&gt;&amp;lt;options allowReassign="false"/&amp;gt;&lt;/pre&gt;


&lt;/div&gt;
&lt;/body&gt;
&lt;/html&gt;
</description></item><item xmlns:s="http://outerx.org/daisywiki/1.0#serializer"><title>Creating a multi role authentication scheme</title><link>http://cocoondev.org/wiki/620-cd</link><description>&lt;html&gt;
&lt;head&gt;
&lt;META http-equiv="Content-Type" content="text/html; charset=UTF-8"&gt;
&lt;base href="http://cocoondev.org"&gt;
&lt;link href="/resources/skins/default/css/daisy.css" type="text/css" rel="stylesheet"&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;div id="diff"&gt;
&lt;div&gt;
&lt;a onclick="document.getElementById('diff').style.display = 'none'; document.getElementById('document').style.display = ''; return false;" href="#"&gt;Show document&lt;/a&gt;
&lt;/div&gt;
&lt;h2&gt;General&lt;/h2&gt;
&lt;table class="default"&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;&lt;th&gt;Version 5&lt;/th&gt;&lt;th&gt;Version 4&lt;/th&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Variant&lt;/td&gt;&lt;td&gt;main - en&lt;/td&gt;&lt;td&gt;main - en&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Document Name&lt;/td&gt;&lt;td&gt;Creating a multi role authentication scheme&lt;/td&gt;&lt;td&gt;Creating a multi role authentication scheme&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Creation time&lt;/td&gt;&lt;td&gt;11/30/08 10:40:40 PM&lt;/td&gt;&lt;td&gt;11/15/08 2:30:35 PM&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Created by&lt;/td&gt;&lt;td&gt;Andreas Deininger&lt;/td&gt;&lt;td&gt;Tim McDonald&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;State:&lt;/td&gt;&lt;td&gt;publish&lt;/td&gt;&lt;td&gt;publish&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;h2&gt;Changes to parts&lt;/h2&gt;
&lt;h3&gt;Part "Content" has changed&lt;/h3&gt;
&lt;br&gt;
&lt;table class="default"&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;&lt;th&gt;Version 5&lt;/th&gt;&lt;th&gt;Version 4&lt;/th&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Mime type&lt;/td&gt;&lt;td&gt;text/xml&lt;/td&gt;&lt;td&gt;text/xml&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;File name&lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Size (bytes)&lt;/td&gt;&lt;td&gt;19950&lt;/td&gt;&lt;td&gt;19950&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;br&gt;
&lt;div class="diffpage-contentdiff-title"&gt;Content changes&lt;/div&gt;
&lt;div class="diffpage-contentdiff"&gt;
&lt;div class="diff-unchanged"&gt;&amp;lt;html&amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;lt;body&amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;lt;p&amp;gt;This step by step instruction explains how to extend the Daisy CMS with your&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;own authentication scheme that fits your needs.&amp;lt;/p&amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;lt;p&amp;gt;&amp;lt;strong&amp;gt;Assumption&amp;lt;/strong&amp;gt;: You already set up daisy on a windows system and&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;everything's working great. Your also doing the codeing and compiling on a&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;separate system (a mac) because you too lazy to install the dev tool on the&lt;/div&gt;
&lt;div class="diff-removed"&gt;windows &lt;span class="diff-removed"&gt;server&lt;/span&gt;...&amp;lt;/p&amp;gt;&lt;/div&gt;
&lt;div class="diff-added"&gt;windows &lt;span class="diff-added"&gt;sever&lt;/span&gt;...&amp;lt;/p&amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;lt;p&amp;gt;&amp;lt;strong&amp;gt;Task&amp;lt;/strong&amp;gt;: You would like new daisy users to be allocated a given&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;role when they first logon. The system admin chaps would ideally like the group&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;the user belongs to on a windows network to dictate this role allocation.&amp;lt;/p&amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;lt;p class="note"&amp;gt;This solution is useful where there are a number of different&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;users who need to see different resources on the same server (ie. student and&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;staff at a university).&amp;lt;/p&amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;lt;h2&amp;gt;Step 1: Checking out the sources&amp;lt;/h2&amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;lt;p&amp;gt;Download the daisy sources daisy-x.x.x.tar.gz of the latest stable (or&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;milestone) release at the&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;lt;a href="http://svn.cocoondev.org/dist/daisy/"&amp;gt;download area&amp;lt;/a&amp;gt; (or&lt;/div&gt;
&lt;div class="diff-removed"&gt;&amp;lt;a href="http://cocoondev.org/daisydocs-1_3/152.html"&amp;gt;check out&amp;lt;/a&amp;gt; the &lt;span class="diff-removed"&gt;latest&lt;/span&gt;
&lt;/div&gt;
&lt;div class="diff-added"&gt;&amp;lt;a href="http://cocoondev.org/daisydocs-1_3/152.html"&amp;gt;check out&amp;lt;/a&amp;gt; the &lt;span class="diff-added"&gt;lastest&lt;/span&gt;
&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;version from SVN, whatever you prefer). Extract the tarball into a directory on&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;your local machine (although you do not have to create that environment&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;variable, I will refer to that directory as DAISY_SRC during the rest ot this&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;tutorial):&amp;lt;/p&amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;lt;pre&amp;gt;$ tar xvzf daisy-x.x.x.tar.gz&amp;lt;/pre&amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;lt;h2&amp;gt;Step 2: Copy the sources of the Ntlm-authentication&amp;lt;/h2&amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;lt;p&amp;gt;Descend to the dircectory $DAISY_SRC/services/ and make a copy of the&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;directory ntlm-auth, which contains the sources for the Ntlm authentication&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;scheme. We take these sources as starting point and we will modify them to fit&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;our needs.&amp;lt;/p&amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;lt;pre&amp;gt;$ cp -R ntlm-auth/ ntlm-group-auth&amp;lt;/pre&amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;lt;h2&amp;gt;Step 3: Create the java classes for authentication&amp;lt;/h2&amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;lt;h3&amp;gt;Step 3a: Rename the existing sourcefiles for AuthenticationFactory and&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;AuthenticationScheme&amp;lt;/h3&amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;lt;p&amp;gt;Descend into the directory&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;$DAISY_SRC/services/ssh-auth/src/java/org/outerj/daisy/authentication/impl&amp;lt;br/&amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;Rename the both existing sourcefiles for the AuthenticationFactory and the&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;AuthenticationScheme&amp;lt;/p&amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;lt;pre&amp;gt;$ mv NtlmAuthenticationFactory.java NtlmGroupAuthenticationFactory.java&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;$ mv NtlmAuthenticationScheme.java NtlmGroupAuthenticationScheme.java&amp;lt;/pre&amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;lt;h3&amp;gt;Step 3b: Edit NTLMGroupAuthenticationFactory.java&amp;lt;/h3&amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;lt;p&amp;gt;In your favourite editor or IDE, edit the source file for the NTLM Group&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;Authentication Factory and change it to:&amp;lt;/p&amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;lt;pre&amp;gt;package org.outerj.daisy.authentication.impl;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;import org.apache.avalon.framework.configuration.Configuration;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;import org.apache.avalon.framework.configuration.ConfigurationException;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;import org.outerj.daisy.authentication.spi.*;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;import org.outerj.daisy.plugin.PluginRegistry;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;import javax.annotation.PreDestroy;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;import java.util.Map;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;import java.util.HashMap;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;/**&lt;/div&gt;
&lt;div class="diff-unchanged"&gt; * Constructs and registers NtlmGroupAuthenticationSchemes with the UserAuthenticator.&lt;/div&gt;
&lt;div class="diff-unchanged"&gt; *&lt;/div&gt;
&lt;div class="diff-unchanged"&gt; */&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;public class NtlmGroupAuthenticationFactory  {&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;    private PluginRegistry pluginRegistry;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;    private Map&amp;amp;lt;String, AuthenticationScheme&amp;amp;gt; schemes = new HashMap&amp;amp;lt;String, AuthenticationScheme&amp;amp;gt;();&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;    public NtlmGroupAuthenticationFactory(Configuration configuration, PluginRegistry pluginRegistry) throws Exception {&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;        this.pluginRegistry = pluginRegistry;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;        this.configure(configuration);&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;        registerSchemes();&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;    }&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;    @PreDestroy&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;    public void destroy() {&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;        unregisterSchemes();&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;    }&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;    private void registerSchemes() throws Exception {&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;        for (Map.Entry&amp;amp;lt;String, AuthenticationScheme&amp;amp;gt; entry : schemes.entrySet()) {&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;            pluginRegistry.addPlugin(AuthenticationScheme.class, entry.getKey(), entry.getValue());&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;        }&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;    }&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;    private void unregisterSchemes() {&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;        for (Map.Entry&amp;amp;lt;String, AuthenticationScheme&amp;amp;gt; entry : schemes.entrySet()) {&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;            pluginRegistry.removePlugin(AuthenticationScheme.class, entry.getKey(), entry.getValue());&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;        }&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;    }&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;    private void configure(Configuration configuration) throws ConfigurationException {&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;        Configuration[] schemeConfs = configuration.getChildren("scheme");&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;        for (Configuration schemeConf : schemeConfs) {&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;            String name = schemeConf.getAttribute("name");&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;            String description = schemeConf.getAttribute("description");&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;            String domainControllerAddress = schemeConf.getChild("domainControllerAddress").getValue();&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;            String domain = schemeConf.getChild("domain").getValue();&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;			
&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;			String file1 = schemeConf.getChild("fileLocation1").getValue();&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;			String file2 = schemeConf.getChild("fileLocation2").getValue();&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;			
&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;			Configuration subUserCreator1 = schemeConf.getChild("subUserCreator1");&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;			UserCreator userCreator1 = UserCreatorFactory.createUser(subUserCreator1, name);&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;			
&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;			
&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;			Configuration subUserCreator2 = schemeConf.getChild("subUserCreator2");			&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;			UserCreator userCreator2 = UserCreatorFactory.createUser(subUserCreator2, name);&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;		
&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;			AuthenticationScheme scheme = new NtlmGroupAuthenticationScheme(name, description, domainControllerAddress, domain, file1, userCreator1, file2, userCreator2);&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;			Configuration cacheConf = schemeConf.getChild("cache");&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;			if (cacheConf.getAttributeAsBoolean("enabled")) {&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;				int maxCacheSize = cacheConf.getAttributeAsInteger("maxCacheSize", 3000);&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;				long maxCacheDuration = cacheConf.getAttributeAsLong("maxCacheDuration", 30 * 60 * 1000); // default: half an hour&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;				scheme = new CachingAuthenticationScheme(scheme, maxCacheDuration, maxCacheSize);&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;			}&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;			if (schemes.containsKey(name))&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;				throw new ConfigurationException("Duplicate authentication scheme name: " + name);&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;			
&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;			schemes.put(name, scheme);&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;				
&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;            
&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;        }&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;    }&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;}&amp;lt;/pre&amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;lt;p&amp;gt;Note that this authentication factory reads in the configuration for two&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;files and userCreators which are then passed to the authentication scheme.&amp;lt;/p&amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;lt;h3&amp;gt;Step 3c: Edit NTLMGroupAuthenticationScheme.java&amp;lt;/h3&amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;lt;p&amp;gt;In your favourite editor or IDE, edit the source file for the NTLM Group&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;Authentication Scheme and change it to:&amp;lt;/p&amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;lt;pre&amp;gt;package org.outerj.daisy.authentication.impl;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;import org.outerj.daisy.authentication.spi.AuthenticationScheme;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;import org.outerj.daisy.authentication.spi.AuthenticationException;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;import org.outerj.daisy.authentication.spi.UserCreator;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;import org.outerj.daisy.repository.Credentials;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;import org.outerj.daisy.repository.user.User;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;import org.outerj.daisy.repository.user.UserManager;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;import jcifs.smb.SmbException;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;import jcifs.smb.SmbAuthException;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;import jcifs.smb.SmbSession;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;import jcifs.smb.NtlmPasswordAuthentication;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;import jcifs.smb.*;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;import jcifs.UniAddress;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;import java.net.UnknownHostException;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;import java.net.MalformedURLException;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;public class NtlmGroupAuthenticationScheme implements AuthenticationScheme {&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;    private final String name;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;    private final String description;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;    private final String domainControllerAddress;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;    private final String domain;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;	private final String file1;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;    private final UserCreator userCreator1;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;	private final String file2;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;    private final UserCreator userCreator2;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;    public NtlmGroupAuthenticationScheme(String name, String description, String domainControllerAddress, String domain, String file1, UserCreator userCreator1, String file2, UserCreator userCreator2) {&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;        this.name = name;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;        this.description = description;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;        this.domainControllerAddress = domainControllerAddress;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;        this.domain = domain;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;		this.file1 = file1;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;		this.userCreator1 = userCreator1;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;		this.file2 = file2;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;        this.userCreator2 = userCreator2;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;    }&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;    public String getName() {&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;        return name;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;    }&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;    public String getDescription() {&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;        return description;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;    }&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;    public boolean check(Credentials credentials) throws AuthenticationException {&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;		if ( check1(credentials) ) {&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;			return true;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;		}&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;		if ( check2(credentials) ) {&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;			return true;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;		}			&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;		return false;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;    }&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;    public boolean check1(Credentials credentials) throws AuthenticationException {&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;        UniAddress mydomaincontroller;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;        try {&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;            mydomaincontroller = UniAddress.getByName(domainControllerAddress);&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;        } catch (UnknownHostException e) {&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;            throw new AuthenticationException("Error authenticating using NTLM.", e);&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;        }&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;        NtlmPasswordAuthentication mycreds = new NtlmPasswordAuthentication(domain, credentials.getLogin(), credentials.getPassword());		&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;		jcifs.Config.registerSmbURLHandler();&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;		SmbFile smbf;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;		try {&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;			smbf = new SmbFile(file1, mycreds);&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;		}	catch( MalformedURLException seed ) {&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;            // NETWORK PROBLEMS?&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;            throw new AuthenticationException("Can't find the file specified", seed);&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;        }&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;        try {			&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;            return smbf.exists();	&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;        } catch( SmbAuthException sae ) {&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;            // AUTHENTICATION FAILURE&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;            return false;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;        } catch( SmbException se ) {&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;            // NETWORK PROBLEMS?&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;            throw new AuthenticationException("Error authenticating using NTLM.", se);&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;        }&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;    }&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;    public boolean check2(Credentials credentials) throws AuthenticationException {&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;        UniAddress mydomaincontroller;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;        try {&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;            mydomaincontroller = UniAddress.getByName(domainControllerAddress);&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;        } catch (UnknownHostException e) {&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;            throw new AuthenticationException("Error authenticating using NTLM.", e);&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;        }&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;        NtlmPasswordAuthentication mycreds = new NtlmPasswordAuthentication(domain, credentials.getLogin(), credentials.getPassword());&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;		
&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;		jcifs.Config.registerSmbURLHandler();&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;		
&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;		SmbFile smbf;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;		
&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;		try {&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;			smbf = new SmbFile(file2, mycreds);&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;		}	catch( MalformedURLException seed ) {&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;            // NETWORK PROBLEMS?&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;            throw new AuthenticationException("Can't find the file specified", seed);&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;        }&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;        try {&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;									
&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;			return smbf.exists();&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;			
&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;        } catch( SmbAuthException sae ) {&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;            // AUTHENTICATION FAILURE&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;            return false;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;        } catch( SmbException se ) {&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;            // NETWORK PROBLEMS?&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;            throw new AuthenticationException("Error authenticating using NTLM.", se);&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;        }&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;    }&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;    public void clearCaches() {&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;        // do nothing&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;    }&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;    public User createUser(Credentials crendentials, UserManager userManager) throws AuthenticationException {&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;        if (userCreator1 != null) {&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;		if (check1(crendentials)) {&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;				User aUser = userCreator1.create(crendentials.getLogin(), userManager);&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;				return aUser;				&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;			}&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;        }&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;		if (userCreator2 != null) {&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;			if (check2(crendentials)) {&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;				User aUser = userCreator2.create(crendentials.getLogin(), userManager);&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;				return aUser;					&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;			}&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;        }&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;        return null;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;    }&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;}&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;lt;/pre&amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;lt;p&amp;gt;The jcifs library which daisy uses to perform NTLM authentication does not&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;provide a simple method for checking if a user belongs to a certain windows&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;group. However, by using the SmbFile() method for the jcifs library we can see&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;if a user with a siven set of creidentials can access a file on a windows share.&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;As a windows server can restrict access using groups this provides a cunning&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;workaround.&amp;lt;/p&amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;lt;p&amp;gt;The location of the file and other parameters are read from a the&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;configuration file myconfig.xml, which we will create later on. This information&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;is used inside the constructor of a new instance of our SSHAuthenticationScheme,&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;which we created above.&amp;lt;/p&amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;lt;p&amp;gt;You'll notice this section of code contains a number of fairly similar&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;methods [i.e. check1() and check2()]. The methods which Daisy itself uses&amp;nbsp; [i.e.&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;check() and createUser()] calls these in order to perform the authentication at&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;the two different levels .&amp;lt;/p&amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;lt;p class="note"&amp;gt;I'm sure there a more elegent way of doing this....&amp;lt;/p&amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;lt;h2&amp;gt;Step 4: Building the authentication scheme&amp;lt;/h2&amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;lt;h3&amp;gt;Step 4a: Compiling and packing your classes&amp;lt;/h3&amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;lt;p&amp;gt;I compile the files on my mac something like this:&amp;lt;/p&amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;lt;p class="note"&amp;gt;Use the method of your choice to compile the code (Ant, Maven,&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;your IDE, ...). When using the command below, we hope you know enough about this&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;that everything should be on one line. For Windows, replace $DAISY_HOME with&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;%DAISY_HOME% and the colons with semicolons)&amp;lt;/p&amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;lt;pre&amp;gt;javac -classpath &lt;/div&gt;
&lt;div class="diff-unchanged"&gt;   ~/Documents/intranet/daisy-2.2/lib/daisy/jars/daisy-repository-api-2.2.jar:&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;   ~/Documents/intranet/daisy-2.2/lib/daisy/jars/daisy-repository-server-spi-2.2.jar:&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;   ~/Documents/intranet/daisy-2.2/lib/daisy/jars/daisy-pluginregistry-api-2.2.jar:&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;   ~/Documents/intranet/daisy-2.2/lib/daisy/jars/daisy-pluginregistry-api-2.2.jar:&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;   ~/Documents/intranet/daisy-2.2/lib/avalon-framework/jars/avalon-framework-api-4.3.jar:&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;   ~/Documents/intranet/daisy-2.2/lib/jcifs/jars/jcifs-1.1.11.jar:&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;   ~/Documents/intranet/daisy-2.2/lib/javax.annotation/jars/jsr250-api-1.0.jar:&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;   ~/Documents/intranet/daisy-2.2/lib/javax.servlet/jars/servlet-api-2.4.jar:&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;   ~/Documents/intranet/ntlm-group-auth/src/org/outerj/daisy/authentication/impl/NtlmGroupAuthenticationScheme.class &lt;/div&gt;
&lt;div class="diff-unchanged"&gt;   ~/Documents/intranet/ntlm-group-auth/src/org/outerj/daisy/authentication/impl/NtlmGroupAuthenticationFactory.java &lt;/div&gt;
&lt;div class="diff-unchanged"&gt;   ~/Documents/intranet/ntlm-group-auth/src/org/outerj/daisy/authentication/impl/NtlmGroupAuthenticationScheme.java&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;jar cvf ntlm-group-auth.jar *&amp;lt;/pre&amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;lt;p&amp;gt;I run this command from the directory shown below:&amp;lt;/p&amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;lt;pre&amp;gt;~/Documents/intranet/ntlm-group-auth/src/&amp;lt;/pre&amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;lt;h3&amp;gt;Step 4b: Copying the jar-file into place&amp;lt;/h3&amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;lt;p&amp;gt;Copy the newly created jar file both into the lib directory of your daisy&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;binary distribution ($DAISY_HOME/lib). Copy the file&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;daisy-auth-ssh-&amp;amp;lt;version&amp;amp;gt;.jar into the directory daisy/jars/.&amp;lt;/p&amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;lt;pre&amp;gt;$ cp target/daisy-auth-ssh-&amp;amp;lt;version&amp;amp;gt;.jar $DAISY_HOME/lib/daisy/jars/&amp;lt;/pre&amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;lt;p class="note"&amp;gt;If you don't want to create a binary distribution of daisy it&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;might be sufficient to copy the jar-file to the $DAISY_HOME/lib directory only.&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;lt;/p&amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;lt;p class="warn"&amp;gt;Details from this point on are a little sketchy, need to check&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;the info on a different PC.&amp;lt;/p&amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;lt;h2&amp;gt;Step 5: Registering and configuring the new component&amp;lt;/h2&amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;lt;h3&amp;gt;Step 5a: Registering the new component&amp;lt;/h3&amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;lt;p&amp;gt;Edit the file $DAISY_HOME/repository-server/conf/block.xml. Inside the&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;container named authentication, include your newly created scheme. The element&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;amp;lt;container&amp;amp;gt; of block.xml now should look like (adapt the versions of your&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;jar files for ntlm and ssh authentication!):&amp;lt;/p&amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;lt;pre&amp;gt;&amp;amp;lt;container name="authentication"&amp;amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;  &amp;amp;lt;services&amp;amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;    &amp;amp;lt;service type="org.outerj.daisy.authentication.UserAuthenticator"&amp;amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;      &amp;amp;lt;source&amp;amp;gt;authenticator&amp;amp;lt;/source&amp;amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;    &amp;amp;lt;/service&amp;amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;    &amp;amp;lt;service type="org.outerj.daisy.authentication.AuthenticationSchemeRegistrar"&amp;amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;      &amp;amp;lt;source&amp;amp;gt;authenticator&amp;amp;lt;/source&amp;amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;    &amp;amp;lt;/service&amp;amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;  &amp;amp;lt;/services&amp;amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;  &amp;amp;lt;component name="authenticator" class="org.outerj.daisy.authentication.impl.UserAuthenticatorImpl"/&amp;amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;  &amp;amp;lt;component name="daisy-native" class="org.outerj.daisy.authentication.impl.DaisyAuthenticationFactory"&amp;amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;    &amp;amp;lt;configuration&amp;amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;      &amp;amp;lt;cache enabled="true" maxCacheSize="3000" maxCacheDuration="1800000"/&amp;amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;    &amp;amp;lt;/configuration&amp;amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;  &amp;amp;lt;/component&amp;amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;  &amp;amp;lt;component name="ldap" class="org.outerj.daisy.authentication.impl.LdapAuthenticationFactory"&amp;amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;    &amp;amp;lt;configuration&amp;amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;      &amp;amp;lt;!-- See myconfig.xml.template for an example configuration --&amp;amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;    &amp;amp;lt;/configuration&amp;amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;  &amp;amp;lt;/component&amp;amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;  &amp;amp;lt;include name="ntlm" id="daisy:daisy-auth-ntlm" version="1.4-dev"/&amp;amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;  &amp;amp;lt;include name="ssh" id="daisy:daisy-auth-ssh" version="1.4-dev"/&amp;amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;  &amp;amp;lt;include name="ntlm-group" id="daisy:daisy-auth-ssh" version="1.4-dev"/&amp;amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;amp;lt;/container&amp;amp;gt;&amp;lt;/pre&amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;lt;h3&amp;gt;Step 5b: Configuring the new component&amp;lt;/h3&amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;lt;p&amp;gt;Inside the directory $DAISY_HOME/repository-server/conf/ you will find a file&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;myconfig.xml.template. Copy this file into the directory conf/ inside your&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;repository and rename it to myconfig.xml&amp;lt;/p&amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;lt;pre&amp;gt;$ cp $DAISY_HOME/repository-server/conf/myconfig.xml.template /path/to/your/repository/conf/myconfig.xml&amp;lt;/pre&amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;lt;p&amp;gt;Edit the newly created file myconfig.xml. Add a target in order to configure&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;your authentication scheme, inside that target, fill in the IP or host name of&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;your SSH-server. Also, in order to enable automatically creation of user&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;accounts once the user logs in to daisy for the first time, define our newly&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;created scheme as authentification scheme for user creation as shown below:&amp;lt;/p&amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;lt;pre&amp;gt;&amp;amp;lt;targets&amp;amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;  &amp;amp;lt;target path="..."&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;    ...&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;  &amp;amp;lt;/target&amp;amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;  ... many more targets&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;  &amp;amp;lt;target path="/daisy/repository/authentication/authenticator"&amp;amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;    &amp;amp;lt;configuration&amp;amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;      &amp;amp;lt;!-- Indicates which authentication scheme to use, if any, to automatically create new users. --&amp;amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;      &amp;amp;lt;authenticationSchemeForUserCreation&amp;amp;gt;ntlmgroup1&amp;amp;lt;/authenticationSchemeForUserCreation&amp;amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;    &amp;amp;lt;/configuration&amp;amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;  &amp;amp;lt;/target&amp;amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;  ... many more targets&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;  &amp;amp;lt;target path="XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"&amp;amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;    &amp;amp;lt;configuration&amp;amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;       &amp;amp;lt;!-- You can configure one or more NTLM-based authentication schemes here --&amp;amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;          &amp;amp;lt;!-- Notes:&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;                - the name of a scheme should not be daisy, no two schemes can have the same name&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;                - the autoCreateUser element is optional&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;          --&amp;amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;          &amp;amp;lt;scheme name="ntlmgroup1" description="Test NTLM Group config"&amp;amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;            &amp;amp;lt;domainControllerAddress&amp;amp;gt;127.0.0.1&amp;amp;lt;/domainControllerAddress&amp;amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;            &amp;amp;lt;domain&amp;amp;gt;yum&amp;amp;lt;/domain&amp;amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;            &amp;amp;lt;cache enabled="true" maxCacheSize="3000" maxCacheDuration="1800000"/&amp;amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;			&amp;amp;lt;fileLocation1&amp;amp;gt;afilelocation&amp;amp;lt;/fileLocation1&amp;amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;			&amp;amp;lt;fileLocation2&amp;amp;gt;afilelocation&amp;amp;lt;/fileLocation2&amp;amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;			&amp;amp;lt;subUserCreator1&amp;amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;			   &amp;amp;lt;autoCreateUser&amp;amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;				  &amp;amp;lt;roles&amp;amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;					&amp;amp;lt;role&amp;amp;gt;User&amp;amp;lt;/role&amp;amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;				  &amp;amp;lt;/roles&amp;amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;				  &amp;amp;lt;defaultRole&amp;amp;gt;User&amp;amp;lt;/defaultRole&amp;amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;				  &amp;amp;lt;updateableByUser&amp;amp;gt;true&amp;amp;lt;/updateableByUser&amp;amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;				&amp;amp;lt;/autoCreateUser&amp;amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;				&amp;amp;lt;test&amp;amp;gt;astring&amp;amp;lt;/test&amp;amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;                         &amp;amp;lt;/subUserCreator1&amp;amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;			 &amp;amp;lt;subUserCreator2&amp;amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;			   &amp;amp;lt;autoCreateUser&amp;amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;				  &amp;amp;lt;roles&amp;amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;					&amp;amp;lt;role&amp;amp;gt;User&amp;amp;lt;/role&amp;amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;				  &amp;amp;lt;/roles&amp;amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;				  &amp;amp;lt;defaultRole&amp;amp;gt;User&amp;amp;lt;/defaultRole&amp;amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;				  &amp;amp;lt;updateableByUser&amp;amp;gt;true&amp;amp;lt;/updateableByUser&amp;amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;				&amp;amp;lt;/autoCreateUser&amp;amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;                         &amp;amp;lt;/subUserCreator2&amp;amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;	&amp;amp;lt;/scheme&amp;amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;    &amp;amp;lt;/configuration&amp;amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;  &amp;amp;lt;/target&amp;amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;amp;lt;/targets&amp;amp;gt;&amp;lt;/pre&amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;lt;h2&amp;gt;Step 6: Running and testing the new scheme&amp;lt;/h2&amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;lt;p&amp;gt;Now we are ready to test our new scheme! Restart the repository server and&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;the daisy wiki.&amp;lt;br/&amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;Try to log on to daisy with any username/password combination which should have&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;permissions to access one of the files at either FileLocation1 or FileLocation2.&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;lt;/p&amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;lt;p&amp;gt;Log in should be successfull, you should be logged on with the role defined&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;in the myconfig.xml configuration file. Login as an administrator, invoke the&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;user administration. In the user list, an account should exist with the username&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;you just logged on as. Also, if you create a new user or edit an existing user,&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;in the drop-down box for the authentication scheme, you now should have the&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;choice between the daisy built in scheme and the scheme we newly created.&amp;lt;/p&amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;lt;p&amp;gt;It's worth noting a couple of points:&amp;lt;/p&amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;lt;ul&amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;lt;li&amp;gt;if a user can access both files at FileLocation1 and FileLocation2 they&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;don't get both sets of roles&amp;lt;/li&amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;lt;li&amp;gt;the roles associated with FileLocation1 and subUserCreator1 are checked&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;before&amp;nbsp; FileLocation2 and subUserCreator1&amp;lt;/li&amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;lt;/ul&amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;lt;p&amp;gt;Best of luck getting it to work. A working example is provided&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;lt;a href="daisy:621-cd"&amp;gt;here&amp;lt;/a&amp;gt;.&amp;lt;/p&amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;lt;p class="warn"&amp;gt;Java's not my strong point; I'd never coded in it before tying&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;this. I'm sure that there's a better way of structuring this code, possibly&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;involving passing arrays of FileLocations and subUserCreators from the&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;authentication factory to the authentication scheme. &amp;lt;em&amp;gt;Please leave some&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;hints. :)&amp;lt;/em&amp;gt;&amp;lt;/p&amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;lt;/body&amp;gt;&lt;/div&gt;
&lt;div class="diff-unchanged"&gt;&amp;lt;/html&amp;gt;&lt;/div&gt;
&lt;/div&gt;
&lt;h2&gt;Changes to links&lt;/h2&gt;
&lt;h3&gt;Removed links&lt;/h3&gt;
&lt;table style="width: 100%" class="default"&gt;
&lt;tr&gt;
&lt;td&gt;Author: Tim McDonald&lt;br&gt;mailto:t_mcdonald@meng.ucl.ac.uk&lt;br&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;h3&gt;Added links&lt;/h3&gt;
&lt;table style="width: 100%" class="default"&gt;
&lt;tr&gt;
&lt;td&gt;Author: Andreas Deininger&lt;br&gt;mailto:andreas@deininger.net&lt;br&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;h2&gt;Changes to fields&lt;/h2&gt;
&lt;span class="diffpage-nochanges"&gt;No changes detected&lt;/span&gt;
&lt;/div&gt;
&lt;div style="display:none" id="document"&gt;
&lt;div&gt;
&lt;a onclick="document.getElementById('diff').style.display = ''; document.getElementById('document').style.display = 'none'; return false;" href="#"&gt;Show diff&lt;/a&gt;
&lt;/div&gt;
&lt;h1 xmlns:d="http://outerx.org/daisy/1.0" xmlns:lt="http://outerx.org/daisy/1.0#linktransformer" xmlns:einclude="http://outerx.org/daisy/1.0#externalinclude" xmlns:p="http://outerx.org/daisy/1.0#publisher" xmlns:i18n="http://apache.org/cocoon/i18n/2.1" xmlns:urlencoder="xalan://java.net.URLEncoder" id="dsy620-cd" class="daisy-document-name"&gt;Creating a multi role authentication scheme&lt;/h1&gt;


&lt;p xmlns:jx="http://apache.org/cocoon/templates/jx/1.0" xmlns:ns="http://outerx.org/daisy/1.0"&gt;This step by step instruction explains how to extend the Daisy CMS with your
own authentication scheme that fits your needs.&lt;/p&gt;


&lt;p&gt;
&lt;strong&gt;Assumption&lt;/strong&gt;: You already set up daisy on a windows system and
everything's working great. Your also doing the codeing and compiling on a
separate system (a mac) because you too lazy to install the dev tool on the
windows server...&lt;/p&gt;


&lt;p&gt;
&lt;strong&gt;Task&lt;/strong&gt;: You would like new daisy users to be allocated a given
role when they first logon. The system admin chaps would ideally like the group
the user belongs to on a windows network to dictate this role allocation.&lt;/p&gt;


&lt;p class="note"&gt;This solution is useful where there are a number of different
users who need to see different resources on the same server (ie. student and
staff at a university).&lt;/p&gt;


&lt;h2&gt;Step 1: Checking out the sources&lt;/h2&gt;


&lt;p&gt;Download the daisy sources daisy-x.x.x.tar.gz of the latest stable (or
milestone) release at the
&lt;a href="http://svn.cocoondev.org/dist/daisy/"&gt;download area&lt;/a&gt; (or
&lt;a href="http://cocoondev.org/daisydocs-1_3/152.html"&gt;check out&lt;/a&gt; the latest
version from SVN, whatever you prefer). Extract the tarball into a directory on
your local machine (although you do not have to create that environment
variable, I will refer to that directory as DAISY_SRC during the rest ot this
tutorial):&lt;/p&gt;


&lt;pre&gt;$ tar xvzf daisy-x.x.x.tar.gz&lt;/pre&gt;


&lt;h2&gt;Step 2: Copy the sources of the Ntlm-authentication&lt;/h2&gt;


&lt;p&gt;Descend to the dircectory $DAISY_SRC/services/ and make a copy of the
directory ntlm-auth, which contains the sources for the Ntlm authentication
scheme. We take these sources as starting point and we will modify them to fit
our needs.&lt;/p&gt;


&lt;pre&gt;$ cp -R ntlm-auth/ ntlm-group-auth&lt;/pre&gt;


&lt;h2&gt;Step 3: Create the java classes for authentication&lt;/h2&gt;


&lt;h3&gt;Step 3a: Rename the existing sourcefiles for AuthenticationFactory and
AuthenticationScheme&lt;/h3&gt;


&lt;p&gt;Descend into the directory
$DAISY_SRC/services/ssh-auth/src/java/org/outerj/daisy/authentication/impl&lt;br&gt;
Rename the both existing sourcefiles for the AuthenticationFactory and the
AuthenticationScheme&lt;/p&gt;


&lt;pre&gt;$ mv NtlmAuthenticationFactory.java NtlmGroupAuthenticationFactory.java
$ mv NtlmAuthenticationScheme.java NtlmGroupAuthenticationScheme.java&lt;/pre&gt;


&lt;h3&gt;Step 3b: Edit NTLMGroupAuthenticationFactory.java&lt;/h3&gt;


&lt;p&gt;In your favourite editor or IDE, edit the source file for the NTLM Group
Authentication Factory and change it to:&lt;/p&gt;


&lt;pre&gt;package org.outerj.daisy.authentication.impl;

import org.apache.avalon.framework.configuration.Configuration;
import org.apache.avalon.framework.configuration.ConfigurationException;
import org.outerj.daisy.authentication.spi.*;
import org.outerj.daisy.plugin.PluginRegistry;

import javax.annotation.PreDestroy;
import java.util.Map;
import java.util.HashMap;

/**
 * Constructs and registers NtlmGroupAuthenticationSchemes with the UserAuthenticator.
 *
 */
public class NtlmGroupAuthenticationFactory  {
    private PluginRegistry pluginRegistry;
    private Map&amp;lt;String, AuthenticationScheme&amp;gt; schemes = new HashMap&amp;lt;String, AuthenticationScheme&amp;gt;();

    public NtlmGroupAuthenticationFactory(Configuration configuration, PluginRegistry pluginRegistry) throws Exception {
        this.pluginRegistry = pluginRegistry;
        this.configure(configuration);
        registerSchemes();
    }

    @PreDestroy
    public void destroy() {
        unregisterSchemes();
    }

    private void registerSchemes() throws Exception {
        for (Map.Entry&amp;lt;String, AuthenticationScheme&amp;gt; entry : schemes.entrySet()) {
            pluginRegistry.addPlugin(AuthenticationScheme.class, entry.getKey(), entry.getValue());
        }
    }

    private void unregisterSchemes() {
        for (Map.Entry&amp;lt;String, AuthenticationScheme&amp;gt; entry : schemes.entrySet()) {
            pluginRegistry.removePlugin(AuthenticationScheme.class, entry.getKey(), entry.getValue());
        }
    }

    private void configure(Configuration configuration) throws ConfigurationException {
        Configuration[] schemeConfs = configuration.getChildren("scheme");
        for (Configuration schemeConf : schemeConfs) {
            String name = schemeConf.getAttribute("name");
            String description = schemeConf.getAttribute("description");
            String domainControllerAddress = schemeConf.getChild("domainControllerAddress").getValue();
            String domain = schemeConf.getChild("domain").getValue();
			
			String file1 = schemeConf.getChild("fileLocation1").getValue();
			String file2 = schemeConf.getChild("fileLocation2").getValue();
			
			Configuration subUserCreator1 = schemeConf.getChild("subUserCreator1");
			UserCreator userCreator1 = UserCreatorFactory.createUser(subUserCreator1, name);
			
			
			Configuration subUserCreator2 = schemeConf.getChild("subUserCreator2");			
			UserCreator userCreator2 = UserCreatorFactory.createUser(subUserCreator2, name);

		
			AuthenticationScheme scheme = new NtlmGroupAuthenticationScheme(name, description, domainControllerAddress, domain, file1, userCreator1, file2, userCreator2);
			Configuration cacheConf = schemeConf.getChild("cache");
			if (cacheConf.getAttributeAsBoolean("enabled")) {
				int maxCacheSize = cacheConf.getAttributeAsInteger("maxCacheSize", 3000);
				long maxCacheDuration = cacheConf.getAttributeAsLong("maxCacheDuration", 30 * 60 * 1000); // default: half an hour
				scheme = new CachingAuthenticationScheme(scheme, maxCacheDuration, maxCacheSize);
			}

			if (schemes.containsKey(name))
				throw new ConfigurationException("Duplicate authentication scheme name: " + name);
			
			schemes.put(name, scheme);
				

            
        }
    }
}&lt;/pre&gt;


&lt;p&gt;Note that this authentication factory reads in the configuration for two
files and userCreators which are then passed to the authentication scheme.&lt;/p&gt;


&lt;h3&gt;Step 3c: Edit NTLMGroupAuthenticationScheme.java&lt;/h3&gt;


&lt;p&gt;In your favourite editor or IDE, edit the source file for the NTLM Group
Authentication Scheme and change it to:&lt;/p&gt;


&lt;pre&gt;package org.outerj.daisy.authentication.impl;

import org.outerj.daisy.authentication.spi.AuthenticationScheme;
import org.outerj.daisy.authentication.spi.AuthenticationException;
import org.outerj.daisy.authentication.spi.UserCreator;
import org.outerj.daisy.repository.Credentials;
import org.outerj.daisy.repository.user.User;
import org.outerj.daisy.repository.user.UserManager;
import jcifs.smb.SmbException;
import jcifs.smb.SmbAuthException;
import jcifs.smb.SmbSession;
import jcifs.smb.NtlmPasswordAuthentication;
import jcifs.smb.*;
import jcifs.UniAddress;

import java.net.UnknownHostException;
import java.net.MalformedURLException;

public class NtlmGroupAuthenticationScheme implements AuthenticationScheme {
    private final String name;
    private final String description;
    private final String domainControllerAddress;
    private final String domain;
	private final String file1;
    private final UserCreator userCreator1;
	private final String file2;
    private final UserCreator userCreator2;

    public NtlmGroupAuthenticationScheme(String name, String description, String domainControllerAddress, String domain, String file1, UserCreator userCreator1, String file2, UserCreator userCreator2) {
        this.name = name;
        this.description = description;
        this.domainControllerAddress = domainControllerAddress;
        this.domain = domain;
		this.file1 = file1;
		this.userCreator1 = userCreator1;
		this.file2 = file2;
        this.userCreator2 = userCreator2;
    }

    public String getName() {
        return name;
    }

    public String getDescription() {
        return description;
    }

    public boolean check(Credentials credentials) throws AuthenticationException {
		if ( check1(credentials) ) {
			return true;
		}
		if ( check2(credentials) ) {
			return true;
		}			
		return false;
    }

    public boolean check1(Credentials credentials) throws AuthenticationException {
        UniAddress mydomaincontroller;
        try {
            mydomaincontroller = UniAddress.getByName(domainControllerAddress);
        } catch (UnknownHostException e) {
            throw new AuthenticationException("Error authenticating using NTLM.", e);
        }
        NtlmPasswordAuthentication mycreds = new NtlmPasswordAuthentication(domain, credentials.getLogin(), credentials.getPassword());		
		jcifs.Config.registerSmbURLHandler();
		SmbFile smbf;
		try {
			smbf = new SmbFile(file1, mycreds);

		}	catch( MalformedURLException seed ) {
            // NETWORK PROBLEMS?
            throw new AuthenticationException("Can't find the file specified", seed);
        }

        try {			
            return smbf.exists();	
        } catch( SmbAuthException sae ) {
            // AUTHENTICATION FAILURE
            return false;
        } catch( SmbException se ) {
            // NETWORK PROBLEMS?
            throw new AuthenticationException("Error authenticating using NTLM.", se);
        }
    }

    public boolean check2(Credentials credentials) throws AuthenticationException {
        UniAddress mydomaincontroller;
        try {
            mydomaincontroller = UniAddress.getByName(domainControllerAddress);
        } catch (UnknownHostException e) {
            throw new AuthenticationException("Error authenticating using NTLM.", e);
        }
        NtlmPasswordAuthentication mycreds = new NtlmPasswordAuthentication(domain, credentials.getLogin(), credentials.getPassword());
		
		jcifs.Config.registerSmbURLHandler();
		
		SmbFile smbf;
		
		try {
			smbf = new SmbFile(file2, mycreds);
		}	catch( MalformedURLException seed ) {
            // NETWORK PROBLEMS?
            throw new AuthenticationException("Can't find the file specified", seed);
        }

        try {
									
			return smbf.exists();
			
        } catch( SmbAuthException sae ) {
            // AUTHENTICATION FAILURE
            return false;
        } catch( SmbException se ) {
            // NETWORK PROBLEMS?
            throw new AuthenticationException("Error authenticating using NTLM.", se);
        }
    }

    public void clearCaches() {
        // do nothing
    }

    public User createUser(Credentials crendentials, UserManager userManager) throws AuthenticationException {
        if (userCreator1 != null) {
		if (check1(crendentials)) {
				User aUser = userCreator1.create(crendentials.getLogin(), userManager);
				return aUser;				
			}
        }
		if (userCreator2 != null) {
			if (check2(crendentials)) {
				User aUser = userCreator2.create(crendentials.getLogin(), userManager);
				return aUser;					
			}
        }
        return null;
    }
}

&lt;/pre&gt;


&lt;p&gt;The jcifs library which daisy uses to perform NTLM authentication does not
provide a simple method for checking if a user belongs to a certain windows
group. However, by using the SmbFile() method for the jcifs library we can see
if a user with a siven set of creidentials can access a file on a windows share.
As a windows server can restrict access using groups this provides a cunning
workaround.&lt;/p&gt;


&lt;p&gt;The location of the file and other parameters are read from a the
configuration file myconfig.xml, which we will create later on. This information
is used inside the constructor of a new instance of our SSHAuthenticationScheme,
which we created above.&lt;/p&gt;


&lt;p&gt;You'll notice this section of code contains a number of fairly similar
methods [i.e. check1() and check2()]. The methods which Daisy itself uses&amp;nbsp; [i.e.
check() and createUser()] calls these in order to perform the authentication at
the two different levels .&lt;/p&gt;


&lt;p class="note"&gt;I'm sure there a more elegent way of doing this....&lt;/p&gt;


&lt;h2&gt;Step 4: Building the authentication scheme&lt;/h2&gt;


&lt;h3&gt;Step 4a: Compiling and packing your classes&lt;/h3&gt;


&lt;p&gt;I compile the files on my mac something like this:&lt;/p&gt;


&lt;p class="note"&gt;Use the method of your choice to compile the code (Ant, Maven,
your IDE, ...). When using the command below, we hope you know enough about this
that everything should be on one line. For Windows, replace $DAISY_HOME with
%DAISY_HOME% and the colons with semicolons)&lt;/p&gt;


&lt;pre&gt;javac -classpath 
   ~/Documents/intranet/daisy-2.2/lib/daisy/jars/daisy-repository-api-2.2.jar:
   ~/Documents/intranet/daisy-2.2/lib/daisy/jars/daisy-repository-server-spi-2.2.jar:
   ~/Documents/intranet/daisy-2.2/lib/daisy/jars/daisy-pluginregistry-api-2.2.jar:
   ~/Documents/intranet/daisy-2.2/lib/daisy/jars/daisy-pluginregistry-api-2.2.jar:
   ~/Documents/intranet/daisy-2.2/lib/avalon-framework/jars/avalon-framework-api-4.3.jar:
   ~/Documents/intranet/daisy-2.2/lib/jcifs/jars/jcifs-1.1.11.jar:
   ~/Documents/intranet/daisy-2.2/lib/javax.annotation/jars/jsr250-api-1.0.jar:
   ~/Documents/intranet/daisy-2.2/lib/javax.servlet/jars/servlet-api-2.4.jar:
   ~/Documents/intranet/ntlm-group-auth/src/org/outerj/daisy/authentication/impl/NtlmGroupAuthenticationScheme.class 
   ~/Documents/intranet/ntlm-group-auth/src/org/outerj/daisy/authentication/impl/NtlmGroupAuthenticationFactory.java 
   ~/Documents/intranet/ntlm-group-auth/src/org/outerj/daisy/authentication/impl/NtlmGroupAuthenticationScheme.java

jar cvf ntlm-group-auth.jar *&lt;/pre&gt;


&lt;p&gt;I run this command from the directory shown below:&lt;/p&gt;


&lt;pre&gt;~/Documents/intranet/ntlm-group-auth/src/&lt;/pre&gt;


&lt;h3&gt;Step 4b: Copying the jar-file into place&lt;/h3&gt;


&lt;p&gt;Copy the newly created jar file both into the lib directory of your daisy
binary distribution ($DAISY_HOME/lib). Copy the file
daisy-auth-ssh-&amp;lt;version&amp;gt;.jar into the directory daisy/jars/.&lt;/p&gt;


&lt;pre&gt;$ cp target/daisy-auth-ssh-&amp;lt;version&amp;gt;.jar $DAISY_HOME/lib/daisy/jars/&lt;/pre&gt;


&lt;p class="note"&gt;If you don't want to create a binary distribution of daisy it
might be sufficient to copy the jar-file to the $DAISY_HOME/lib directory only.
&lt;/p&gt;


&lt;p class="warn"&gt;Details from this point on are a little sketchy, need to check
the info on a different PC.&lt;/p&gt;


&lt;h2&gt;Step 5: Registering and configuring the new component&lt;/h2&gt;


&lt;h3&gt;Step 5a: Registering the new component&lt;/h3&gt;


&lt;p&gt;Edit the file $DAISY_HOME/repository-server/conf/block.xml. Inside the
container named authentication, include your newly created scheme. The element
&amp;lt;container&amp;gt; of block.xml now should look like (adapt the versions of your
jar files for ntlm and ssh authentication!):&lt;/p&gt;


&lt;pre&gt;&amp;lt;container name="authentication"&amp;gt;
  &amp;lt;services&amp;gt;
    &amp;lt;service type="org.outerj.daisy.authentication.UserAuthenticator"&amp;gt;
      &amp;lt;source&amp;gt;authenticator&amp;lt;/source&amp;gt;
    &amp;lt;/service&amp;gt;
    &amp;lt;service type="org.outerj.daisy.authentication.AuthenticationSchemeRegistrar"&amp;gt;
      &amp;lt;source&amp;gt;authenticator&amp;lt;/source&amp;gt;
    &amp;lt;/service&amp;gt;
  &amp;lt;/services&amp;gt;

  &amp;lt;component name="authenticator" class="org.outerj.daisy.authentication.impl.UserAuthenticatorImpl"/&amp;gt;

  &amp;lt;component name="daisy-native" class="org.outerj.daisy.authentication.impl.DaisyAuthenticationFactory"&amp;gt;
    &amp;lt;configuration&amp;gt;
      &amp;lt;cache enabled="true" maxCacheSize="3000" maxCacheDuration="1800000"/&amp;gt;
    &amp;lt;/configuration&amp;gt;
  &amp;lt;/component&amp;gt;

  &amp;lt;component name="ldap" class="org.outerj.daisy.authentication.impl.LdapAuthenticationFactory"&amp;gt;
    &amp;lt;configuration&amp;gt;
      &amp;lt;!-- See myconfig.xml.template for an example configuration --&amp;gt;
    &amp;lt;/configuration&amp;gt;
  &amp;lt;/component&amp;gt;

  &amp;lt;include name="ntlm" id="daisy:daisy-auth-ntlm" version="1.4-dev"/&amp;gt;
  &amp;lt;include name="ssh" id="daisy:daisy-auth-ssh" version="1.4-dev"/&amp;gt;
  &amp;lt;include name="ntlm-group" id="daisy:daisy-auth-ssh" version="1.4-dev"/&amp;gt;

&amp;lt;/container&amp;gt;&lt;/pre&gt;


&lt;h3&gt;Step 5b: Configuring the new component&lt;/h3&gt;


&lt;p&gt;Inside the directory $DAISY_HOME/repository-server/conf/ you will find a file
myconfig.xml.template. Copy this file into the directory conf/ inside your
repository and rename it to myconfig.xml&lt;/p&gt;


&lt;pre&gt;$ cp $DAISY_HOME/repository-server/conf/myconfig.xml.template /path/to/your/repository/conf/myconfig.xml&lt;/pre&gt;


&lt;p&gt;Edit the newly created file myconfig.xml. Add a target in order to configure
your authentication scheme, inside that target, fill in the IP or host name of
your SSH-server. Also, in order to enable automatically creation of user
accounts once the user logs in to daisy for the first time, define our newly
created scheme as authentification scheme for user creation as shown below:&lt;/p&gt;


&lt;pre&gt;&amp;lt;targets&amp;gt;
  &amp;lt;target path="..."
    ...
  &amp;lt;/target&amp;gt;

  ... many more targets

  &amp;lt;target path="/daisy/repository/authentication/authenticator"&amp;gt;
    &amp;lt;configuration&amp;gt;
      &amp;lt;!-- Indicates which authentication scheme to use, if any, to automatically create new users. --&amp;gt;
      &amp;lt;authenticationSchemeForUserCreation&amp;gt;ntlmgroup1&amp;lt;/authenticationSchemeForUserCreation&amp;gt;
    &amp;lt;/configuration&amp;gt;
  &amp;lt;/target&amp;gt;

  ... many more targets

  &amp;lt;target path="XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"&amp;gt;
    &amp;lt;configuration&amp;gt;
       &amp;lt;!-- You can configure one or more NTLM-based authentication schemes here --&amp;gt;
          &amp;lt;!-- Notes:
                - the name of a scheme should not be daisy, no two schemes can have the same name
                - the autoCreateUser element is optional
          --&amp;gt;
          &amp;lt;scheme name="ntlmgroup1" description="Test NTLM Group config"&amp;gt;
            &amp;lt;domainControllerAddress&amp;gt;127.0.0.1&amp;lt;/domainControllerAddress&amp;gt;
            &amp;lt;domain&amp;gt;yum&amp;lt;/domain&amp;gt;
            &amp;lt;cache enabled="true" maxCacheSize="3000" maxCacheDuration="1800000"/&amp;gt;
			&amp;lt;fileLocation1&amp;gt;afilelocation&amp;lt;/fileLocation1&amp;gt;
			&amp;lt;fileLocation2&amp;gt;afilelocation&amp;lt;/fileLocation2&amp;gt;
			&amp;lt;subUserCreator1&amp;gt;
			   &amp;lt;autoCreateUser&amp;gt;
				  &amp;lt;roles&amp;gt;
					&amp;lt;role&amp;gt;User&amp;lt;/role&amp;gt;
				  &amp;lt;/roles&amp;gt;
				  &amp;lt;defaultRole&amp;gt;User&amp;lt;/defaultRole&amp;gt;
				  &amp;lt;updateableByUser&amp;gt;true&amp;lt;/updateableByUser&amp;gt;
				&amp;lt;/autoCreateUser&amp;gt;
				&amp;lt;test&amp;gt;astring&amp;lt;/test&amp;gt;
                         &amp;lt;/subUserCreator1&amp;gt;
			 &amp;lt;subUserCreator2&amp;gt;
			   &amp;lt;autoCreateUser&amp;gt;
				  &amp;lt;roles&amp;gt;
					&amp;lt;role&amp;gt;User&amp;lt;/role&amp;gt;
				  &amp;lt;/roles&amp;gt;
				  &amp;lt;defaultRole&amp;gt;User&amp;lt;/defaultRole&amp;gt;
				  &amp;lt;updateableByUser&amp;gt;true&amp;lt;/updateableByUser&amp;gt;
				&amp;lt;/autoCreateUser&amp;gt;
                         &amp;lt;/subUserCreator2&amp;gt;
	&amp;lt;/scheme&amp;gt;
    &amp;lt;/configuration&amp;gt;
  &amp;lt;/target&amp;gt;
&amp;lt;/targets&amp;gt;&lt;/pre&gt;


&lt;h2&gt;Step 6: Running and testing the new scheme&lt;/h2&gt;


&lt;p&gt;Now we are ready to test our new scheme! Restart the repository server and
the daisy wiki.&lt;br&gt;
Try to log on to daisy with any username/password combination which should have
permissions to access one of the files at either FileLocation1 or FileLocation2.
&lt;/p&gt;


&lt;p&gt;Log in should be successfull, you should be logged on with the role defined
in the myconfig.xml configuration file. Login as an administrator, invoke the
user administration. In the user list, an account should exist with the username
you just logged on as. Also, if you create a new user or edit an existing user,
in the drop-down box for the authentication scheme, you now should have the
choice between the daisy built in scheme and the scheme we newly created.&lt;/p&gt;


&lt;p&gt;It's worth noting a couple of points:&lt;/p&gt;


&lt;ul&gt;

&lt;li&gt;if a user can access both files at FileLocation1 and FileLocation2 they
don't get both sets of roles&lt;/li&gt;

&lt;li&gt;the roles associated with FileLocation1 and subUserCreator1 are checked
before&amp;nbsp; FileLocation2 and subUserCreator1&lt;/li&gt;

&lt;/ul&gt;


&lt;p&gt;Best of luck getting it to work. A working example is provided
&lt;a title="ntlm-group-auth" href="/wiki/621-cd/version/default/part/AttachmentData/data/ntlm-group-auth.jar"&gt;here&lt;/a&gt; (application/octet-stream, 11.4 kB, &lt;a href="/wiki/621-cd.html"&gt;info&lt;/a&gt;).&lt;/p&gt;


&lt;p class="warn"&gt;Java's not my strong point; I'd never coded in it before tying
this. I'm sure that there's a better way of structuring this code, possibly
involving passing arrays of FileLocations and subUserCreators from the
authentication factory to the authentication scheme. &lt;em&gt;Please leave some
hints. :)&lt;/em&gt;
&lt;/p&gt;


&lt;div class="doclinks"&gt;
&lt;h2&gt;Links&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;a href="mailto:t_mcdonald@meng.ucl.ac.uk"&gt;Author: Tim McDonald&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/body&gt;
&lt;/html&gt;
</description></item></channel></rss>