Hi All This is the index to a series of articles I hope to create over the coming months.
ZEN and ZEN Mojo are no longer being actively developed by Intesystems - this is a great shame as it is a fine product that works so well for business applications. However ZEN is a 15 year old product and I need a path forward to replace the ZEN UI with a supported development framework.
This article is an index of the other articles I have, or plan to write. - the articles will be subject to change as I develop my thoughts and climb the learning curve.
I enjoy the challenge of being in a contest. Currently I participate in InterSystems IRIS with REST API Programming Contest. My idea for this contest was to create an app to help me keep track of tasks for my Status Reports. I started with the template provided by Evgeny Shvarov. I created a persistent class for Tasks and a REST Dispatch class. I defined my URL map and I even figured out how to test my REST app using Postman.
I am an avid user of ZEN for over 10 years now and it works for me. But it seems that Intersystems are no longer actively developing it (or ZEN Mojo), the only published reference to this is here
I just want to share with you the knowledge aka experience which could save you a few hours someday.
If you are building REST API with IRIS which contains more than 1 level of "/", e.g. '/patients/all' don't forget to add parameter 'recurse=1' into your deployment script in %Installer, otherwise all the second and higher entries won't work. And all the entries of level=1 will work.
/patients
- will work, but
/patients/all
- won't.
Here is an example of CSPApplicatoin section which fix the issue and which you may want to use in your %Installer class:
I this article I detail some strategic issues that a new development UI will need to address - these are the ones that I can think of now - others may come to light during this journey.
See the webinar by Eduard Lebedyuk here from the last Global Summit describing modern web development and Caché
And, as always, if I have missed something please comment....
Here is an ObjectScript snippet which lets to create database, namespace and a web application for InterSystems IRIS:
set currentNS = $namespace
zn "%SYS"
write "Create DB ...",!
set dbName="testDB"
set dbProperties("Directory") = "/InterSystems/IRIS/mgr/testDB"
set status=##Class(Config.Databases).Create(dbName,.dbProperties)
write:'status $system.Status.DisplayError(status)
write "DB """_dbName_""" was created!",!!
write "Create namespace ...",!
set nsName="testNS"
//DB for globals
set nsProperties("Globals") = dbName
//DB for routines
set nsProperties("Routines") = dbName
set status=##Class(Config.Namespaces).Create(nsName,.nsProperties)
write:'status $system.Status.DisplayError(status)
write "Namespace """_nsName_""" was created!",!!
write "Create web application ...",!
set webName = "/csp/testApplication"
set webProperties("NameSpace") = nsName
set webProperties("Enabled") = $$$YES
set webProperties("IsNameSpaceDefault") = $$$YES
set webProperties("CSPZENEnabled") = $$$YES
set webProperties("DeepSeeEnabled") = $$$YES
set webProperties("AutheEnabled") = $$$AutheCache
set status = ##class(Security.Applications).Create(webName, .webProperties)
write:'status $system.Status.DisplayError(status)
write "Web application """webName""" was created!",!
zn currentNS
IRIS provides us with anti login CSRF attack mitigation, however this is not the same as a CSRF attack, as login attacks only occur on the login form. There are currently no built-in tools to mitigate CSRF attacks on api calls and other forms, so this is a step in mitigating these attacks.
See the following link from OWASP for the definition of a CSRF attack:
The Caché / Ensemble standard distribution contains in namespace SAMPLES a nice example of a CSP page consuming WebService as a Client. I have modified it not only to display the replies but to feed them back into a Global. I used the classic Hyperevent to achieve this. The replies end up as a log in global^WSREPLY. When there is no input anymore the page closes and goes away.
There are 2 versions with visible and hidden display during operation. dc.WSCSP.reverseVerbose.cls and dc.WSCSP.reverseHidden.cls
This is a quick note on what happens when, on your CSP page, you call a cache script which returns a %Boolean and store that value in a javascript variable.
When you call a script with language="cache" and returntype="%Boolean" from a javascript script, the return value is interpreted as a string, not as a boolean.
Here's an example:
A cache script that returns (in theory) a "false" value:
In our last lesson, we added a relationship between 2 persistent classes. We are clearly going to need to start creating REST Services to expose CRUD operations for each of these classes, but before we do that, we should really finish defining our linkages. We added code to our Widget toJSON to spool off related Accessory data, so we should really do the reciprocal and allow Accessories to return all Widgets that are compatible.
or "Didn't you say you would cover Persistent Objects in Part 5, Chris?"
Yes, that was the plan. This is a pretty important topic, so it get's its own Article
Up until now, we've display widget JSON that has been created by a basic loop. Clearly this isn't of much value. Now we have our stack connected together, and we can see that the data is flowing to the Welcome page, it's time to complete the stack and start feeding our service from "real" data.
In our last lesson, we implemented a new REST Service to allow us to perform CRU operations on Widgets, and refactored our Controllers to allow the page setup to be decouple from the content.
A key part of Application Performance Management (APM) is recording the activity and performance of user activity. For many web applications the closest you can get to this is to record the CSP pages or CSP based services being dispatched.
In our last lesson, we implemented a linkage to our WidgetAccessory class, and debugged some errors we encountered along the way. We now have our data being returned by REST, but what if we want to update or add new data to our application?
We left our application over the weekend, secure in the knowledge that it was returning data from our primary persistent class, User.Widget. However, Widgets Direct are the premier supplier of both Widgets AND Widget Accessories, so we should really start working on adding these Accessories to our application.
We finished our last lesson with our Widgets Direct page iterating over a list of widgets, displaying an ID and a Name value. While we have been able to achieve this with only a small amount of coding, the page itself is not the most visually appealing place to be. The AngularJS framework is providing a powerful Model-View-Controller framework for our structure and logic, but it does not implement anything that will provide a nice UI experience.
At the end of our last lesson, we ended with our page displaying a nice (but garish) Angular Material Toolbar, and our Widget data displaying in a list of Material cards. Our page feels a bit static, and we already know that the large number of Widgets that we will be dealing with will not be especially usable on a static list. What can we do to help?
If you are developing applications that use CSP or Zen, or potentially any of the other InterSystems web-related stuff that's built on top of CSP, then it's important to know how to keep one particular secret.
A central part of the CSP security architecture is a server-side session key. "Server-side" because its value should never be revealed to the client that is issuing the web requests. If it is revealed, a malicious client might be able to use it to bypass your security and make your server do things you don't want it to.
We finished our last lesson with our Widgets Direct page receiving a Welcome message as a property of a JSON object, which was unpacked and displayed on the page. However, we are on Lesson 3, and we still haven't had any talk of displaying widgets yet.
In this recent post I highlighted the importance of a CSP session's Key property in enforcing the level of security your web application may be relying on, and in particular the need to keep the property value secret.
I am configuring IIS to work with the CSP Gateway but I'm running into this error:
"The Module DLL 'C:\Inetpub\CSPGateway\CSPms.dll' could not be loaded due to a configuration problem. The current configuration only supports loading images built for a x86 processor architecture."