Using SPAuditQuery to surface users that have read a document, but are part of a Group
-
10-12-2019 - |
Question
I am using the following code to return the details of users that have read a document:
private List<Int32> GetWhoHasRead()
{
List<Int32> returnList = new List<Int32>();
//run in elevated priveleges
SPSecurity.RunWithElevatedPrivileges(delegate()
{
using (SPSite rootSite = new SPSite(SPContext.Current.Site.Url))
{
using (SPWeb rootWeb = rootSite.OpenWeb())
{
//get the library
SPList testList = rootWeb.Lists["LibraryOne"];
//get the document
SPListItem item = testList.Items[0];
//we want to know who viewed the document
item.Audit.AuditFlags = SPAuditMaskType.View;
SPAuditQuery query = new SPAuditQuery(rootSite);
query.RestrictToListItem(item);
SPAuditEntryCollection entries = rootSite.Audit.GetEntries(query);
//loopy loop
foreach (SPAuditEntry entry in entries)
{
if (entry.Event == SPAuditEventType.View)
{
//show who has read the document
SPUser readUser = rootWeb.AllUsers.GetByID(entry.UserId);
txtRead.Text += readUser.LoginName + "\r\n";
returnList.Add(readUser.ID);
}
}
}
}
});
return returnList;
}
The line:
SPAuditEntryCollection entries = rootSite.Audit.GetEntries(query);
returns too few results. As far as I can tell it is not returning users that have viewed the document, who are in an ad group that has been granted access.
Does anyone know how to get around this, or where I am going wrong?
Thanks!!
Solution
You can check the AuditData table with a query in the content database. Then you will be sure that your code is the problem.
If you are sure that your code is the problem then check the following:
Users that are assigned permissions in SharePoint only through AD groups they are not added in SharePoint users information list in the site. If you check in siteCollUrl/_catalogs/users/simple.aspx you will not find those users but you will find the AD group added as SharePoint principal. Add all users members of that AD group to the SharePoint site (for example by adding them to a dummy group) and run your code again.
Few remarks for your code which are not related with your problem but will improve your code:
item.Audit.AuditFlags is used to set the flags to configure which events should SharePoint register. That line does nothing in your code.
For querying only View events use SPAuditQuery.AddEventRestriction(SPAuditEventType.View) . Then you don’t need the If part to check is it a View event or not.
private List<Int32> GetWhoHasRead()
{
List<Int32> returnList = new List<Int32>();
//run in elevated priveleges
SPSecurity.RunWithElevatedPrivileges(delegate()
{
using (SPSite rootSite = new SPSite(SPContext.Current.Site.Url))
{
using (SPWeb rootWeb = rootSite.OpenWeb())
{
//get the library
SPList testList = rootWeb.Lists["LibraryOne"];
//get the document
SPListItem item = testList.Items[0];
SPAuditQuery query = new SPAuditQuery(rootSite);
query.RestrictToListItem(item);
//we want to know who viewed the document
query.AddEventRestriction(SPAuditEventType.View);
SPAuditEntryCollection entries = rootSite.Audit.GetEntries(query);
//loopy loop
foreach (SPAuditEntry entry in entries)
{
//show who has read the document
SPUser readUser = rootWeb.AllUsers.GetByID(entry.UserId);
txtRead.Text += readUser.LoginName + "\r\n";
returnList.Add(readUser.ID);
}
}
}
});
return returnList;
}