Filed under: Best Practices
  Comments: None

In NexJ Studio, it is possible to provide record-level view security on any class. This means it’s possible to handle scenarios where we want only non-deleted employee records to be visible to all non-admin users, while admin users should be able to see all the employee records.

Record-level view security is set by specifying the access attribute on the read event of a class. In NexJ Studio, by convention, the access attribute is set to an attribute called “readable”. Scheme code can be written in the readable attribute and is then interpreted by the framework and eventually converted to an SQL query. The following are examples that illustrate how to use the readable attribute.

Example:No Users Should Have Access

Assume there are records of type Entity in the database. Some of these records are “soft deleted” and should not be visible to the end user. Access to these records can be controlled by first overriding the read event of Entity and setting its access property to the “readable” attribute:

And then setting the readable attribute of the Entity class to the following:

Now running (Entity'read '() '() '() '() '() #f)executes the underlying query (select A.id from NJEntity A where A.deletedFlag = 0). The query shows that no Entity record with a deletedFlag value of true will be returned to the end user.

Example:Subset of Users Should Have Access

Assume the same situation as above. However this time we have an administrative user (userA) with a privilege “EntityViewAllDeleted” and we want users with that privilege to be able to view all Entity records. This can be accomplished by changing the readable attribute as follows:

Now executing (Entity'read '() '() '() '() '() #f) from userA’s point of view generates the underlying query (select A.id from NJEntity A)which would return all records as expected. However, executing it from any other user’s point of view would generate  (select A.id from NJEntity A where A.deletedFlag = 0) which would once again only return Entity records that have a false deletedFlag value.

Readable Attribute Restrictions

Framework evaluates Scheme code written in the readable attribute to SQL statements. As such there are certain restrictions on what can be and cannot appear in the readable attribute:

  • Advanced Scheme expressions such as cond cannot be used.
  • Functions cannot be used to build the WHERE clause.
  • The keyword “this” is not recognized but the equivalent macro “@” is.

Record-Level View Security Best Practices

Due to the way the readable attribute is handled, a slight change can have a great effect on overall application performance. As such, the following are a few guidelines to follow when making changes to the readable attribute:

  • Avoid using “or” statements. Use “if” statements instead as framework can evaluate the if condition at run time if possible before compiling the SQL statement and in turn reduce the amount of joins/attributes requested. Also, attempt to make the ”if” statement something that can be evaluated before reading from the database. Using conditions such as  (in-privilege? “Admin”) which can be evaluated before hitting the database instead of   (= (@ attr) ,value) can help maintain performance. However, it is perfectly understandable that this cannot always be done.
  • Always attempt to define the readable attribute on the first concrete class that is persisted. For example, if we have the Entity class, which is persisted, and we have two more classes, Person and Company, which are children of Entity, then the readable attribute should be defined on Entity.

 

Be the first to write a comment.

Your feedback

You must be logged in to post a comment.