Deconstructing the New Entry Process
So far, in analysing the forum application,
we have only considered application channels which are concerned
with retrieving information
and presenting it with either an XHTML, RSS, or Atom view.
Now lets consider the paths and application channels that are
used to create new entries.
In the web-application the paths which modify the application data are as follows:
Path |
Description |
/forum/post/new-topic |
Post a new topic in a forum. |
/forum/post/new-entry |
Post a new entry in a topic. |
/forum/post/new-message |
Send a mediated anonymous email message to another forum member. |
/forum/post/preview |
Preview service for BBcode - renders BBcode submissions to XHTML block.
This service is dynamically called using AJAX by each of the message posting services
described above. |
/forum/profile/ |
View and change a members profile. |
/forum/moderate/forum/[forum-id]/[page] |
The paginated moderators view of topics in a forum. |
/forum/moderate/topic/[topic-id]/[page] |
The paginated moderators view of entries in a topic. |
In a moment we will explore the new-topic path, but first we should note that all of these paths require user authentication
before they may be accessed. Lets take a moment to examine how access control is applied to these paths...
Access Control
Access control is the process of constraining access to
portions of an application to users with the appropriate
authority.
To implement access control the identity of each user must be
established.
This is usually accomplished by requiring the user to present
some sort of token or secret information (such as a username
and password).
In web applications this appears to be a "log-in" step.
After a user has identified themselves, the application can
associate an access token with their session,
eliminating the need for them to reestablish
their identity.
The forum uses a layered URI gatekeeper to handle authentication and
token validation - a detailed guide to the operation of the
URI gatekeeper is provided here
.
If we look at the forum-web module definition
we can see the following rewrite rules...
<rewrite>
<!---->
<rule>
<match>(active:.*/(post|profile).*)</match>
<to>active:gk+uri@$1</to>
</rule>
<!---->
<rule>
<match>(active:gk.*/(post|profile).*|ffcpl:/forum/moderate.*)</match>
<to>active:sessionmapper+uri@$e1</to>
</rule>
</rewrite>
The first rule maps any active: matching the paths /post or /profile to the active:gk accessor. The second rule
matches any active:gk or moderator requests to the active:sessionmapper. This is an example of the functional
overlay pattern, lets consider what these rules mean in terms of functions...
If f(x) is any URI matching active:.*/(post|profile.*) then the first rewrite rule defines g(f(x)) as active:gk+uri@f(x).
The second rule matches any URI function g(f(x)) and wraps it as h(g(f(x))) to active:sessionmapper+uri@g((f(x)).
So the net result is that these rules wrap the original request f(x) inside two outer function evaluations h(g(f(x))).
Another way to view this is in terms of Aspect Oriented Programming (AOP).
NetKernel intrinsically follows the AOP paradigm for each request to the kernel.
Adding the gatekeeper is exactly the same as adding an AOP intercept point
in an Object Oriented (OO) based system such as Java.
The wrapper functions have the following purpose:
the active:sessionmapper function reconnects a session cookie holding an authentication token to a session URI
(for details see the session guide
) and appends this as a 'session' argument on the subsequent call to active:gk
the
URI gatekeeper which establishes the validity of the session before finally evaluating f(x) which is the service call matching the /post or /profile paths.
The policies which declaratively define session mapping and gatekeeper zones can be found in the etc/ directory. Note that the GateKeeperPolicy.xml defines
internal services for validity assertion and credential presentation - these are called by the gatekeeper accessor prior to any access being granted to the desired uri.
The implementation code which performs validation and credential checking can be found the main/forum/access/ directory.
Finally since these are functional overlays they are transparent to the application operation which means we can return to our consideration of the paths which
modify data safe in the knowledge that trust is being managed on the boundary of the module.
Deconstructing the New Topic Path
Lets now return to looking at the new-topic path which is exposed on the public web interface at ffcpl:/forum/post/new-topic.
If we inspect the module definition we see that this path is mapped by default to the mapper accessor (it also gets wrapped by access control and session management
as described above and which we no longer need to consider.)
In the primary_links.xml we find that ffcpl:/forum/post/new-topic matches the following link...
<link>
<name>topics-new</name>
<ext>/post/new-topic</ext>
<int>active:dpml+operand@ffcpl:/main/forum/topic/edit/new-topic-form.idoc</int>
<args>links,param,session</args>
</link>
The new-topic-form.idoc DPML script returns an XHTML block containing the BBcode submission form. The form is generated by the XSL transform
ffcpl:/main/forum/common/bbform.xsl. The resulting XHTML fragment contains the submission form and some simple helper
scripts for supporting BBcode tags. It also contains an AJAX script to perform the live preview of the form data.
The AJAX script registers a keypress event detector keyUp(e) - if the user types a space ' ', a fullstop '.' or a close-square
bracket ']' then an AJAX post of the form data to the BBcode preview service is triggered. The preview service is located at ffcpl:/forum/post/preview
and simply parses and renders BBcode to an XHTML block. The response of the
preview service is pasted into a "preview-block" div block below the form. The AJAX BBcode form and preview services have been constructed to
be common and are configured and used by the new-topic, new-entry and new-message application channels.
When the form is submitted the new-topic-form.idoc script calls new-topic-submit.idoc.
This script is responsible for processing the BBcode tagged submission into XHTML by calling entry-process.idoc, it then invokes the data services
to create the new topic (ffcpl:/forum-edit-new-topic) and adds the XHTML entry under the topic (ffcpl:/forum-edit-new-entry), finally an HTTP redirect is constructed
to redirect to the URL path of the newly created topic.
Now lets look at the implementation of the data service ffcpl:/forum-edit-new-topic in the forum-services module. This service adds a new topic to the database.
By examining the delegated mapper interface we see that this uri matches the link...
<link>
<ext>/forum-edit-new-topic</ext>
<int>active:dpml+operand@ffcpl:/forum/edit/new-topic.idoc</int>
<args>links,param,token</args>
</link>
This link invokes the DPML script ffcpl:/forum/edit/new-topic.idoc.
Notice that the 'token' argument has been passed all the way through - this contains the URI of the
authenticated session token which was established on the forum-web module's interface and which is the proxy identifier for the user.
In the first instruction this token is converted into a user-id by calling the /security/getUser.idoc.
The script then constructs and issues an SQL statement to update the topic table with a new topic.
Lastly the script constructs the golden thread URI associated with this forum - namely gt:/forum/[id]. Finally both the constructed golden thread and the
gt:/forum-metadata golden thread are cut. This action invalidates all cached resources which are dependent on these virtual golden thread resources.
Any subsequent request to view the topic will find no entry in the cache view and will proceed down the topic channel to regenerate the view. Furthermore
since the overall forum's metadata (total number of topics and entries) has been changed, any view which is associated with the gt:/forum-metadata golden thread will
also be regenerated to reflect the new state - this includes the front-page. This is an example of the
golden thread pattern.