OpenNTF.org - UserAccessDetails class - allo
    Advanced
   OpenNTF Code Bin
Edit Document Code By Date > Code Document
About This Code
Brief Description:
UserAccessDetails class - allows consistent access to a user's access level 
Rating:
Not Rated Yet 
Contributor:
Dallas Gimpel 
Category:
Lotusscript 
Type:
Security 
Notes Version:
R6.x, R7.x 
Last Modified:
19 Dec 2007 
OpenNTF Disclaimer

All of the program code and information presented in the OpenNTF.org Code Bin are provided "as-is", and should be used at your own risk. OpenNTF.org make no express or implied warranty about anything in the Code Bin, and OpenNTF.org will not be responsible or liable for any damage caused by the use or misuse of anything from this site. OpenNTF.org makes no guarantees about anything. Please thoroughly test all of the knowledge and code you find here before you attempt to use them in your production environment.

Code / Description

In my experience, the native LotusScript methods are usually fine provided that:

  • the code in question is running on a server, or
  • the user happens to be explicitly defined in the Access Control List (and you don't necessarily need a union of all roles, etc), or
  • the "Enforce a consistent Access Control List across all replicas" property is enabled on the database.

If one or more of these conditions is not true, the native functions may not behave as expected. Catch that last part from the Designer Help for the QueryAccessRoles method of the NotesDatabase class:
    "If the name you specify is not listed explicitly in the ACL, QueryAccess checks to see if the name is a member of a group in the primary address book where the program is running: on a workstation the Personal Address Book; on a server the Domino Directory."
So if your code is executed on a workstation as opposed to a server, the QueryAccess method uses the local NAB. This poses a problem when resolving group membership. Enabling the "...consistent Access Control List..." property seems to (at least) alleviate the problem. But that may not always be an option, in which case, QueryAccessRoles may not work as desired. That was one of the reasons I wrote this class which provides an interface to most aspects of a specific user's access to a specific database. The class accounts for group memberships and wildcard entries in the ACL.


Public Properties:
    CLASS_NAME
      Return value: String constant, name of this class (mostly for use in error handling)

    PUBLIC_NAB_REPLICAID
      Return value: String constant, replica ID of the public Name & Address Book (or Domino Directory if you prefer)

    DEFAULT_ARRAY_VALUE
      Return value: String constant, value to which arrays are initialized

    GetACL
      Return value: NotesACL, a handle to the ACL of the database for this instance

    GetProperACLEntry
      Return value: NotesACLEntry, a handle to the explicitly defined ACL entry for the specified user to the specified database for this instance (may be nothing)

    GetActiveEntries
      Return value: Variant, (string array) all active ACL entry names for the specified user to the specified database

    GetActiveRoles
      Return value: Variant, (string array) a union of all active ACL roles for the specified user to the specified database

    GetAccessLevel
      Return value: Integer, access level (as defined by NotesACLEntry class) for the specified user to the specified database

    CanDelete
      Return value: Boolean, true if specified user has access to delete documents in the specified database, otherwise false

Constructor:
    Sub New(pndbTarget As NotesDatabase, pstrUName As String)
      Description: class contructor
      Parameters:
        pndbTarget - NotesDatabase, database to which access details are to be compiled
        pstrUName - String, the user name for which access details are to be compiled

Public Methods:
    Sub Delete()
      Description: class destructor, executes by default when a given instance of the class is dereferenced
      Parameters:
        none

    Sub ReleaseNotesObjects()
      Description: releases all Notes handles except for the target NotesDatabase
      Parameters:
        none

    Sub Initialize()
      Description: a convenient way of collecting all access details
      Parameters:
        none

Private Methods:
Function setNAB()
    Description: Attempts get a handle to the public name and address via the PUBLIC_NAB_REPLICAID constant.
    Return value: Boolean, true if successful, otherwise false.
    Parameters:
      none

Function setGroupView(pviewOut As NotesView)
    Description: Attempts get a handle to the NotesView used for accessing group documents.
    Return value: Boolean, true if successful, otherwise false.
    Parameters:
      pviewOut - NotesView, receives a handle to the NotesView used for accessing group documents

Function getActiveACLEntries()
    Description: Attempts to compute all active ACL entries by which a given user has access to a database.
    Return value: Boolean - true if successful, otherwise false.
    Parameters:
      none

Function getActiveACLRoles()
    Description: Attempts to compute a union of all active ACL roles a given user possesses for a given database.
    Return value: Boolean - true if successful, otherwise false.
    Parameters:
    none

Function detectDeleteAccess()
    Description: Attempts to determine whether or not a given user has delete access to a given database.
    Return value: Boolean - true if successful, otherwise false.
    Parameters:
      none

Function getMaxAccessLevel()
    Description: Returns the maximum access level a given user has for a given database.
    Return value: Integer, the maximum access level determined for a given user to a given database.
    Parameters:
      none

Function expandGroupMembers(pstrGroupName As String, pvarGroupMembersOut As Variant)
    Description: Attempts to resolve the individual members of a given group name by evaluating an @Function.
    Return value: Boolean - true if successful, otherwise false.
    Parameters:
      pstrGroupName - String, the group name whose members are to be resolved
      pvarGroupMembersOut - Variant, receives the names of the individual group members

Function getGroupMembers(pviewGroups As NotesView, pstrGroupName As String) -
    Description: Attempts to resolve the individual members of a given group name by way of a NotesView in the Public Name & Address Book
    Return value: Variant, the names of the individual group members
    Parameters:
      pviewGroups - NotesView, active handle to the view to be used for accessing group documents
      pstrGroupName - String, group name for which group members are to be computed

Sub processError() -
    Description: Module is used to handle internal errors within the class.
    Parameters:
      none

Additional Notes:
  • Be sure to change the "PUBLIC_NAB_REPLICAID" constant to match your Public NAB's replica id.
  • This version of the class was intended to be used in the UI (as evidenced by the use of Messageboxes), but it can easily be modified to be used in a server-based agent if necessary.
Usage / Example
Suggested Implementation:
    The attachment below contains a database with a single LS library. You'll need to edit the library and replace the "PUBLIC_NAB_REPLICAID" property's value with a valid replica id that points to the Public NAB in your environment. Then you can copy the library to the desired database and use it as needed.

Example usage:
    Dim nsess as NotesSession
    Dim uzrAxs as UserAccessDetails
    Dim strMsgTxt as String

    Set nsess = New NotesSession()
    Set uzrAxs = New UserAccessDetails(nsess.CurrentDatabase, nsess.UserName)

    strMsgTxt$ = "Active entries: " & Chr(13) & Join(uzrAxs.GetActiveEntries, Chr(13))
    strMsgTxt$ = strMsgTxt$ & Chr(13) & "Active roles: " & Chr(13) & Join(uzrAxs.GetActiveRoles, Chr(13))
    strMsgTxt$ = strMsgTxt$ & Chr(13) & "Access level: " & uzrAxs.GetAccessLevel

    if uzrAxs.CanDelete then
      strMsgTxt$ = strMsgTxt$ & Chr(13) & "Delete access was detected."
    else
      strMsgTxt$ = strMsgTxt$ & Chr(13) & "Delete access was NOT detected."
    end if

    msgbox strMsgTxt$, , "Results . . ."
Code Attachments
 Comments

No documents found

 Add your comment!