PreviousNext…

Tip #6: using roles in Lotusscript

Background

ACL roles can be very useful as a way of protecting sections of a database from casual users. For example, an application could have an "Administrators" option that only works for those with the [Administrators] ACL role.

All well and good, but if you're just using that to control access to a view or something, there are ways and means to get around such measures.

The code below is very simple, and is designed to be used in a form Queryopen event. A variation of this should also be used in the Querymodechange event, to cope with users who select "Edit" directly form views.

It tests to see whether the current user has a certain role, before deciding whether they can edit the document using this form or not. As an added bonus, note that this particular code excerpt also demonstrates one way of ensuring an application only has one central configuration document, rather than several, without resorting to profiles.

Assumptions

The current form is called / aliased "frmConfig"
The administrative role in the ACL is called "[Administrators]"

Why is this code of any use / interest whatsoever?

I find myself using Lotusscript in form events quite a lot, so mixing in @formula such as @IsMember(@UserRoles; "[Administrators]")) isn't really an option. Also, I often want to avoid the use of Readers / Authors fields in situations such as this. In this example, the code is designed to prevent casual editing of a database configuration document. The use of Readers fields isn't a valid approach, because I want every user to be able to access values within this document, and Authors fields are similarly useless, due to the standard level of access being Editor.

The code (with my clear and well-written narrative omitted for brevity :-D

%REM
If this is a new document, checks whether a configuration
document already exists in the database. If it does, tells the
user, & stops before they go ahead and create another one,
which would just cause problems. Also prevents users without
the [Administrators] role from editing this document.
%ENDREM

Dim session As New NotesSession
Dim db As NotesDatabase
Dim dc As NotesDocumentCollection
Dim strQuery As String
Dim dt As New NotesDateTime("21/09/1972")
Dim doc As NotesDocument
Dim varAccessTest As Variant

' // Duplicate check
If IsNewDoc Then
strQuery = {Form="frmConfig"}
Set db = session.CurrentDatabase
Set dc = db.Search(strQuery, dt, 0)
If dc.Count <> 0 Then
Messagebox "Halting: a configuration document already exists in this database.", 0, "Error"
Continue = False
End If
End If

' // Edit mode / ACL role check
varAccessTest = Evaluate("@IsNotMember(""[Administrators]""; @UserRoles)")
If Source.EditMode And varAccessTest(0) = "1" Then
Messagebox "Sorry, but you don't have edit rights to this document.", 0, "Access Error"
Continue = False
Exit Sub
End If

Useful? Hope so. And hey, you saw it here first: Ben Poole finally finds a valid use for the Evaluate statement!

Comments

  1. hi ben, I extensively use evaluate statements for manipulating lists in lotus script, it's pretty useful and simple Regards Pavanpavan#
  2. I have been using Evaluate a lot since I came across this DB in the LDD Sandbox

    I use Evaluate now for pretty much anything that exists in @formulas in my LotusScript. @Word, @ReplaceSubString, @IsMember and @DbLookup, etc. As I understand it, using Evaluate is much faster.

    I have run some tests doing lookups into a view (that contains basically every document in the DB) in a 1.4GB DB. I tested:

    1. "Traditional" LotusScript lookup. GetView, GetDocumentByKey(key), docV.ColumnValues(col)…
    2. "Evaluate" lookup.
    3. Search, which of course was the worst.

    Method 2 was (nearly - I imagine that what other tasks my PC was running would effect this) always faster. Plus, it is so much easier writing 1 or 2 lines for the Evaluate - I also find, as this site has already pointed out, that putting complicated strings together for your Evaluate, using squigly brackets {} SO much easier than quotes.

    I used the "StopWatch" classes, which I got from www.eview.com for timing, which I find quite useful for testing code which runs for too long.

    Great Site by the way.

    Nick#
  3. Thanks for your response. Agreed, the stopwatch classes are very useful, I've used them in the past (more in R4). I would like to do some testing with ND6, given the wholesale re-write of the @formula engine… I reckon formulae / Evaluate are going to be even faster then…

    However, getting documents via a view vs. NotesDatabase.Search is a trickier beast. I've had varying results with this one. I think the best choice comes down to a number of variables:

    • Number of docs in database
    • Number of views
    • View indexing
    • Size of view index you're performing a GetDocument call on
    • Number of docs being scanned / read / updated / whatever as a proportion of the overall database document count.

    Whatever the results, one thing we should never do is GetNthDocument, eh! Cheers for your comments.

    Ben Poole#

Comments on this post are now closed.

About

I’m a software architect / developer / general IT wrangler specialising in web, mobile web and middleware using things like node.js, Java, C#, PHP, HTML5 and more.

Best described as a simpleton, but kindly. You can read more here.

";