Search This Blog

Wednesday, January 16, 2013

How to protect a subset of items in a NotesDocument

Hi guys

Let's imagine that you work on some application that contains some sales data.
Usually, such solutions are quite sensitive to the questions about who can see and what can see through the application.

Let's say that your application is mainly used by two kinds of users: managers and salesmen.

Managers can see all documents and all items inside of accessed documents.
Salesmen should see only subset of documents and even for accessed documents they should see only subset of items.

Let's think about how it can be done.

The first part, regarding handling of access right on a document level is obvious - we can rely on READERS fields, so all we need to do is just to put a [Manager] role and Notes Names of required salesmen into such field. Though this is not the best option from the performance standpoint I would go this way anyway since it is the simplest approach.

Now we get to the most tricky part (from the my point of view) of this task: how are we going to implement protection of some items with already accessed document?

Well, I did not find solution I would really like :-) I think I am just not smart enough ;-)
Though I implemented some workable solution I described below I decided to publish this post here because I hope to get some nice advises from you about how it could be done better. So, guys, if you can teach me, please do, I would really appreciate that :-)

Okay, how did I choose the solution that I implemented eventually?

I considered next possibilities:
  1. Hidden formulas
  2. Taking out the items which should be protected to separate document accessible only by Domino Server
  3. Encryption
  4. Complete data separation

1) Hidden formulas or why we can not use this way :-)

We hide field using a hidden formula - user gets its value using a document properties dialog window

We hide the database design to prevent users from accessing the document properties dialog window

User creates a private agent with lotus script like below and use it on selected document

We disable user's ability to create private agents in database through its ACL

User creates an agent in any other database and modifies lotus script from the previous example a little

This is not the complete list of possible scenarios which allow user to ignore such dumb protection. I described a couple of scenarios just to show you that every of them does not work.


2) Why approach with taking out the items to separate document accessible only by Domino Server is bad

My explanation is simple - database with such solution can not work on local.

Such approach means that items which should be protected are taking out to the separate document that has a READERS field with the only Domino server's name. At some point protected data should be extracted from this document with the Domino server rights and put to the NotesDocument that is opened by user. It can be done through NotesAgent.RunOnServer() method or somehow else...

However, as soon as database gets on local - users can not reach protected data. For salesmen, people who visit customers and often work outside of a local network what sometimes means "without connection to server", such solution can be unacceptable.

3) Encryption

Actually, encryption is a safe way, I swear :-) but you have to consider if it is the only one possible option for you since it will be a complicated solution for sure.

We have two basic encryption possibilities:
  • synchronous encryption with only a secret key
  • asynchronous encryption with a pair of public and secret key
It is hard to imagine how you can use the first encryption option for such kind of applications. There are to much questions here: who will be responsible for generating of secret keys, should secret keys be generated per user or per salesmen group, how is it supposed to distribute secret keys, how will it work for roaming users with many workplaces, how will it work from the Web, what should be done if secret key is lost etc.


If we take the second encryption option then it is much better. 
As you may know it is possible to encrypt any Lotus Notes document with a public key of some person (or with a bunch of public keys of several persons).


So this possibility gives us a really nice way to achieve our goal - to protect a subset of items. 
We just need to enable encryption for required field and use lotus script for doing other things.

However there is at least one thing we have to take into account with such solution: users without proper decryption key can not open such document for editing at all, even if you enabled encryption for only one field. So if we want to encrypt some fields but save ability to edit this document for users without decryption keys we need to carry out encrypted fields to some separate document and work with it on QueryOpen or PostOpen events of parent document.

However this is a good approach and if my application has a complicated logic I would go this way.

4) Complete data separation

Though previous approach looked good enough I used this way.
I could let myself to go this way because my application was very simple.
It just contained plain NotesDocuments with sales data without any complicated logic, dependencies etc.
In the most of cases users just read data from this application.

So I implemented functionality that creates and manages pairs of documents:

  • first document with all items and READERS field = [Manager] role
  • second document with subset of items and READERS field = [SalesMan NotesName]
Of course, I had to care about processing a pair of documents everywhere through the database but as I said this application was mainly read by users that's why it was easy.

In conclusion I want to ask you to share with me other approaches you may know about how to protect a subset of items in a NotesDocument 

No comments:

Post a Comment