2
votes

I have a navigation bar at the top of my Xpages applications. This element is going to be shared among many Xpage apps - it will work kind of like a intranet for our Xpage apps.

I do not want to display databases links to users who do not have access to the database.

How do I determine if a user can access a db? And is this something that I should somehow cache, so it doesn't have to be loaded again and again:

3

3 Answers

3
votes

You can use the Database method queryAccess(name) to get the ACL level for the individual user. You can then check for No Access and for Depositor. Here's an example that returns true if the user has access to db:

db.queryAccess(userName) != ACL.LEVEL_NOACCESS && db.queryAccess(userName) != ACL.LEVEL_DEPOSITOR

I will suggest that you cache this in a user bean for the user.

3
votes

Per's suggestion is great but be aware of one limitation on queryaccess:

From the documentation:

If the name you specify is listed explicitly in the ACL, queryAccess returns the access level for that ACL entry and does not check the groups. If the name you specify is not listed explicitly in the ACL, queryAccess checks if the name is a member of a group in the primary Address Book known to the computer on which the script is running. On a local workstation, that address book is the Personal Address Book. On a server, that address book is the Domino® Directory. If queryAccess finds the name in one or more groups, it returns the highest access level among those groups. If the name you specify is not listed in the ACL either individually or as part of a group, queryAccess returns the default access level for the ACL.

3
votes

First of all - if code runs under user's privileges, you can't call queryAccess for database you can't open. To work around this you could force the code to use signer's session and get the access. But...

I recommend this: make a bean named hasAccess. About the scope:

  • application scope is shared among users - useless
  • session scope - quite fine, but in case of ACL change you would need to restart http or wait for session timeout
  • view scope is recommended
  • request scope wont help much

Implement map interface, so you can bind it like #{hasAccess[database]} where database will be filepath, or some special key to lookup database. Implement cache and return true/false, according to user's access. How do you determine user's access is up to you, but I think the best method is to use try/catch with attempt to open that database and check it with isOpen().