ext/ACLHelper/UserSecurity.cs
// https://stackoverflow.com/a/22020271/14894786
using System.IO;
using System.Security.AccessControl;
using System.Security.Principal;
namespace Intern.Helpers.ACLHelper
{
public class UserSecurity
{
private WindowsIdentity _user;
private WindowsPrincipal _principal;
public UserSecurity()
{
_user = WindowsIdentity.GetCurrent();
_principal = new WindowsPrincipal(_user);
}
public UserSecurity(WindowsIdentity identity)
{
_user = identity;
_principal = new WindowsPrincipal(_user);
}
public bool HasAccess(DirectoryInfo directory, FileSystemRights right)
{
// Get the collection of authorization rules that apply to the directory.
AuthorizationRuleCollection acl = directory.GetAccessControl()
.GetAccessRules(true, true, typeof(SecurityIdentifier));
return HasFileOrDirectoryAccess(right, acl);
}
public bool HasAccess(FileInfo file, FileSystemRights right)
{
// Get the collection of authorization rules that apply to the file.
AuthorizationRuleCollection acl = file.GetAccessControl()
.GetAccessRules(true, true, typeof(SecurityIdentifier));
return HasFileOrDirectoryAccess(right, acl);
}
private bool HasFileOrDirectoryAccess(FileSystemRights right,
AuthorizationRuleCollection acl)
{
bool allow = false;
bool inheritedAllow = false;
bool inheritedDeny = false;
for (int i = 0; i < acl.Count; i++)
{
var currentRule = (FileSystemAccessRule)acl[i];
// If the current rule applies to the current user.
if (_user.User.Equals(currentRule.IdentityReference) ||
_principal.IsInRole(
(SecurityIdentifier)currentRule.IdentityReference))
{
if (currentRule.AccessControlType.Equals(AccessControlType.Deny))
{
if ((currentRule.FileSystemRights & right) == right)
{
if (currentRule.IsInherited)
{
inheritedDeny = true;
}
else
{ // Non inherited "deny" takes overall precedence.
return false;
}
}
}
else if (currentRule.AccessControlType
.Equals(AccessControlType.Allow))
{
if ((currentRule.FileSystemRights & right) == right)
{
if (currentRule.IsInherited)
{
inheritedAllow = true;
}
else
{
allow = true;
}
}
}
}
}
if (allow)
{ // Non inherited "allow" takes precedence over inherited rules.
return true;
}
return inheritedAllow && !inheritedDeny;
}
}
}