Search code examples
lotus-noteslotusscriptlotuslotus-formula

How to prevent some users to open a document from a Lotus view?


I have:

  • a Lotus view which holds lots of documents,
  • a field X on every document, which holds users, who should be able to open this document.

How can I prvent opening a particular document for all users except those listed in filed X? I guess this could be done through QueryOpenDocument event, but would need some assistance on how to construct the code.

Thanks.


Solution

  • QueryOpenDocument, view selection formula and other things like that are not a good way to prevent users from opening your document as a security measure.

    A user may create a personal view or copy your database and/or documents to another place (flash usb, etc).

    Security measures should involve:

    1. Encryption (via public and/or secret encryption keys)
    2. Readers access, via Readers field (a special field, which content is usernames of authorized users, who can read this document).

    In some cases you may need to prevent opening a document from view, not for security reasons, but just to solve a particular task.

    For instance, if your view shows documents which should not be opened with any form.

    In this case, open view in designer, go to QueryOpenDocument and add some code like that:

    Sub Queryopendocument(Source As Notesuiview, Continue As Variant)
        Dim doc2BeOpened As NotesDocument
    
        Set doc2BeOpened =  Source.Documents.getFirstDocument()
    
        'checking MyField value to decide, open or not open the document
        If doc2BeOpened.MyField(0) = "some value" Then
            continue = False 'preventing `open document` action
        End If
    End Sub
    

    To allow opening a document make sure that Continue variable is equal to True. It is True by default.




    UPDATE №1

    If your document contains a list of common user names, then you can use the following code:

    Sub Queryopendocument(Source As Notesuiview, Continue As Variant)
    
        Dim session As New NotesSession
        Dim userName As String
        Dim whoAllowed2ViewDoc As Variant
    
        Dim doc2BeOpened As NotesDocument
    
        userName = session.CommonUserName
    
        Set doc2BeOpened =  Source.Documents.getFirstDocument()
    
        'let say your field name is AllowedPeopleNames
        'you can use doc2BeOpened.AllowedPeopleNames or doc2BeOpened.GetItemValue("AllowedPeopleNames")
        'both (without (0) at the end, will return you a variant array with names)
        whoAllowed2ViewDoc = doc2BeOpened.GetItemValue("AllowedPeopleNames")
    
        If Not Isnumeric(Arraygetindex(whoAllowed2ViewDoc, userName)) Then
            continue = False 'preventing `open document` action if userName is not listed in whoAllowed2ViewDoc array   
        End If  
    End Sub
    

    Please note, that the code above works for common user names.

    • John Smith - is a common username
    • John Smith\IT\Acme - is abbreviated username
    • CN=John Smith\OU=IT\O=Acme - is fully qualified name (canonical form).

    To get fully qualified name (also named as canonical form), you can use session.username To get abbreviated form of name, get fully qualified username, then use NotesName class, built with fully qualified name as a parameter and then get an abbreviated form of name from it.

    Dim notesName as NotesName
    Dim abbreviatedUserName as String
    
    Set notesName = New NotesName( fullyQualifiedName )
    abbreviatedUserName = notesName.Abbreviated
    




    UPDATE №2

    Be careful when checking username presence in the array. The first thing you need to determine what form is using for names, stored in that (field) array AllowedPeopleNames.

    If names in this array looks like:

    "John Smith"
    "Luis Brown"
    "Antony Stoppard"
    

    then this array contains common usernames, and you need to get username for checking like that:

    Dim session as New NotesSession
    Dim username as String
    
    username = session.CommonUserName
    

    If names in this array looks like:

    "John Smith/IT/Acme"
    "Luis Brown/IT/Acme"
    "Antony Stoppard/IT/Acme"
    

    then this array contains names in abbreviated form. And you need to get username for further checking using this approach:

    Dim session as New NotesSession
    Dim notesName as New NotesName(session.username)
    Dim username as String
    
    username = notesName.abbreviated
    

    And If names in this array looks like:

    "CN=John Smith/OU=IT/O=Acme"
    "CN=Luis Brown/OU=IT/O=Acme"
    "CN=Antony Stoppard/OU=IT/O=Acme" 
    

    then it contains names in canonical form. And you should get username for checking with this array using the following approach:

    Dim session as New NotesSession
    Dim username as String
    
    username = session.username
    

    Hope this helps.