public virtual bool CanAccess(IFileEntry entry, FileEntryRights rights) { Guard.NotNull(entry, nameof(entry)); if (entry is not(LocalFile or LocalDirectory) || !entry.Exists) { throw new InvalidOperationException($"For file permission checks given entry must be an existing local/physical file or directory. Entry: '{entry.SubPath}'"); } switch (Environment.OSVersion.Platform) { case PlatformID.Win32NT: if (OperatingSystem.IsWindows()) { return(CanAccessOnWindows(entry, rights)); } break; case PlatformID.Unix: return(CanAccessOnLinux(entry, rights)); } return(false); }
protected virtual bool CanAccessOnWindows(IFileEntry entry, FileEntryRights rights) { var canAccess = true; var identity = WindowsIdentity.GetCurrent(); var denyRead = false; var denyWrite = false; var denyModify = false; var denyDelete = false; var allowRead = false; var allowWrite = false; var allowModify = false; var allowDelete = false; try { var rules = GetAccessControl(entry).GetAccessRules(true, true, typeof(SecurityIdentifier)) .Cast <FileSystemAccessRule>() .ToList(); foreach (var rule in rules.Where(rule => identity.User?.Equals(rule.IdentityReference) ?? false)) { CheckRule(rule); } if (identity.Groups != null) { foreach (var reference in identity.Groups) { foreach (var rule in rules.Where(rule => reference.Equals(rule.IdentityReference))) { CheckRule(rule); } } } allowDelete = !denyDelete && allowDelete; allowModify = !denyModify && allowModify; allowRead = !denyRead && allowRead; allowWrite = !denyWrite && allowWrite; if (rights.HasFlag(FileEntryRights.Read)) { canAccess = allowRead; } if (rights.HasFlag(FileEntryRights.Write)) { canAccess = canAccess && allowWrite; } if (rights.HasFlag(FileEntryRights.Modify)) { canAccess = canAccess && allowModify; } if (rights.HasFlag(FileEntryRights.Delete)) { canAccess = canAccess && allowDelete; } } catch (IOException) { return(false); } catch { return(true); } return(canAccess);