/// <summary> /// Processes the renaming of a directory. /// </summary> /// <param name="provider">The provider.</param> /// <param name="oldName">The old directory name (full path).</param> /// <param name="newName">The new directory name (full path).</param> /// <returns><c>true</c> if the operation completed successfully, <c>false</c> otherwise.</returns> /// <remarks>The method <b>does not</b> recurse in sub-directories.</remarks> public bool ProcessDirectoryRenaming(IFilesStorageProviderV60 provider, string oldName, string newName) { if (provider == null) { throw new ArgumentNullException("provider"); } if (oldName == null) { throw new ArgumentNullException("oldName"); } if (oldName.Length == 0) { throw new ArgumentException("Old Name cannot be empty", "oldName"); } if (newName == null) { throw new ArgumentNullException("newName"); } if (newName.Length == 0) { throw new ArgumentException("New Name cannot be empty", "newName"); } return(_settingsProvider.AclManager.RenameResource( Actions.ForDirectories.ResourceMasterPrefix + AuthTools.GetDirectoryName(provider, oldName), Actions.ForDirectories.ResourceMasterPrefix + AuthTools.GetDirectoryName(provider, newName))); }
/// <summary> /// Deletes a directory and de-indexes all its contents. /// </summary> /// <param name="provider">The provider.</param> /// <param name="directory">The directory to delete.</param> public static bool DeleteDirectory(IFilesStorageProviderV60 provider, string directory) { if (provider == null) { throw new ArgumentNullException("provider"); } if (directory == null) { throw new ArgumentNullException("directory"); } if (directory.Length == 0 || directory == "/") { throw new ArgumentException("Cannot delete the root directory", "directory"); } directory = NormalizeFullPath(directory); // This must be done BEFORE deleting the directory, otherwise there wouldn't be a way to list contents DeletePermissions(provider, directory); DeindexDirectory(provider, directory); // Delete Directory bool done = provider.DeleteDirectory(directory); if (!done) { return(false); } Host.Instance.OnDirectoryActivity(provider.GetType().FullName, directory, null, FileActivity.DirectoryDeleted); return(true); }
/// <summary> /// Recursively re-indexes all the contents of the old (renamed) directory to the new one. /// </summary> /// <param name="provider">The provider.</param> /// <param name="oldDirectory">The old directory.</param> /// <param name="newDirectory">The new directory.</param> private static void ReindexDirectory(IFilesStorageProviderV60 provider, string oldDirectory, string newDirectory) { oldDirectory = NormalizeFullPath(oldDirectory); newDirectory = NormalizeFullPath(newDirectory); // At this point the directory has been already renamed, // thus we must list on the new directory and construct the old name // Example: /directory/one/ renamed to /directory/two-two/ // List on /directory/two-two/ // dir1 // dir2 // oldSub = /directory/one/dir1/ foreach (string sub in provider.ListDirectories(newDirectory)) { string oldSub = oldDirectory + sub.Substring(newDirectory.Length); ReindexDirectory(provider, oldSub, sub); } foreach (string file in provider.ListFiles(newDirectory)) { string oldFile = oldDirectory + file.Substring(newDirectory.Length); SearchClass.RenameFile(provider.CurrentWiki, provider.GetType().FullName + "|" + oldFile, provider.GetType().FullName + "|" + file); } }
/// <summary> /// Retrieves the subjects that have ACL entries set for a directory. /// </summary> /// <param name="provider">The provider.</param> /// <param name="directory">The directory.</param> /// <returns>The subjects.</returns> public SubjectInfo[] RetrieveSubjectsForDirectory(IFilesStorageProviderV60 provider, string directory) { if (provider == null) { throw new ArgumentNullException("provider"); } if (directory == null) { throw new ArgumentNullException("directory"); } if (directory.Length == 0) { throw new ArgumentException("Directory cannot be empty", "directory"); } AclEntry[] entries = _settingsProvider.AclManager.RetrieveEntriesForResource(Actions.ForDirectories.ResourceMasterPrefix + AuthTools.GetDirectoryName(provider, directory)); List <SubjectInfo> result = new List <SubjectInfo>(entries.Length); for (int i = 0; i < entries.Length; i++) { SubjectType type = AuthTools.IsGroup(entries[i].Subject) ? SubjectType.Group : SubjectType.User; // Remove the subject qualifier ('U.' or 'G.') string name = entries[i].Subject.Substring(2); if (result.Find(delegate(SubjectInfo x) { return(x.Name == name && x.Type == type); }) == null) { result.Add(new SubjectInfo(name, type)); } } return(result.ToArray()); }
/// <summary> /// Gets all the actions for a directory that are denied to a subject. /// </summary> /// <param name="subject">The subject.</param> /// <param name="provider">The provider.</param> /// <param name="directory">The directory.</param> /// <returns>The denied actions.</returns> private string[] RetrieveDenialsForDirectory(string subject, IFilesStorageProviderV60 provider, string directory) { if (provider == null) { throw new ArgumentNullException("provider"); } if (directory == null) { throw new ArgumentNullException("directory"); } if (directory.Length == 0) { throw new ArgumentException("Directory cannot be empty", "directory"); } string resourceName = Actions.ForDirectories.ResourceMasterPrefix + AuthTools.GetDirectoryName(provider, directory); AclEntry[] entries = _settingsProvider.AclManager.RetrieveEntriesForSubject(subject); List <string> result = new List <string>(entries.Length); foreach (AclEntry entry in entries) { if (entry.Value == Value.Deny && entry.Resource == resourceName) { result.Add(entry.Action); } } return(result.ToArray()); }
/// <summary> /// Deletes and de-indexes a file. /// </summary> /// <param name="provider">The provider.</param> /// <param name="fullName">The full name of the file to delete.</param> /// <returns><c>true</c> if the file was deleted, <c>false</c> otherwise.</returns> public static bool DeleteFile(IFilesStorageProviderV60 provider, string fullName) { if (provider == null) { throw new ArgumentNullException("provider"); } if (fullName == null) { throw new ArgumentNullException("fullName"); } if (fullName.Length == 0) { throw new ArgumentException("Full Name cannot be empty", "fullName"); } fullName = NormalizeFullName(fullName); bool done = provider.DeleteFile(fullName); if (!done) { return(false); } SearchClass.UnindexFile(provider.GetType().FullName + "|" + fullName, provider.CurrentWiki); Host.Instance.OnFileActivity(provider.GetType().FullName, fullName, null, FileActivity.FileDeleted); return(true); }
/// <summary> /// Removes all the ACL Entries for a directory that are bound to a subject. /// </summary> /// <param name="subject">The subject.</param> /// <param name="provider">The provider.</param> /// <param name="directory">The directory.</param> /// <returns><c>true</c> if the operation succeeded, <c>false</c> otherwise.</returns> private bool RemoveEntriesForDirectory(string subject, IFilesStorageProviderV60 provider, string directory) { if (provider == null) { throw new ArgumentNullException("provider"); } if (directory == null) { throw new ArgumentNullException("directory"); } if (directory.Length == 0) { throw new ArgumentException("Directory cannot be empty", "directory"); } string resourceName = Actions.ForDirectories.ResourceMasterPrefix + AuthTools.GetDirectoryName(provider, directory); AclEntry[] entries = _settingsProvider.AclManager.RetrieveEntriesForSubject(subject); foreach (AclEntry entry in entries) { if (entry.Resource == resourceName) { // This call automatically logs the operation result bool done = SetPermissionForDirectory(AuthStatus.Delete, provider, directory, entry.Action, subject); if (!done) { return(false); } } } return(true); }
public void Init() { IFilesStorageProviderV60 prov = GetProvider(); prov.Init(MockHost(), ConfigurationManager.AppSettings["AzureConnString"], "wiki1"); Assert.IsNotNull(prov.Information, "Information should not be null"); }
public void Init() { IFilesStorageProviderV60 prov = GetProvider(); prov.Init(MockHost(), "", null); Assert.IsNotNull(prov.Information, "Information should not be null"); }
/// <summary> /// Gets all the actions for a directory that are denied to a group. /// </summary> /// <param name="group">The user group.</param> /// <param name="provider">The provider.</param> /// <param name="directory">The directory.</param> /// <returns>The denied actions.</returns> public string[] RetrieveDenialsForDirectory(UserGroup group, IFilesStorageProviderV60 provider, string directory) { if (group == null) { throw new ArgumentNullException("group"); } return(RetrieveDenialsForDirectory(AuthTools.PrepareGroup(group.Name), provider, directory)); }
/// <summary> /// Gets all the actions for a directory that are denied to a user. /// </summary> /// <param name="user">The user.</param> /// <param name="provider">The provider.</param> /// <param name="directory">The directory.</param> /// <returns>The denied actions.</returns> public string[] RetrieveDenialsForDirectory(UserInfo user, IFilesStorageProviderV60 provider, string directory) { if (user == null) { throw new ArgumentNullException("user"); } return(RetrieveDenialsForDirectory(AuthTools.PrepareUsername(user.Username), provider, directory)); }
/// <summary> /// Sets a permission for a directory. /// </summary> /// <param name="status">The authorization status.</param> /// <param name="provider">The provider that handles the directory.</param> /// <param name="directory">The directory.</param> /// <param name="action">The action of which to modify the authorization status.</param> /// <param name="user">The user subject of the authorization change.</param> /// <returns><c>true</c> if the authorization status is changed, <c>false</c> otherwise.</returns> public bool SetPermissionForDirectory(AuthStatus status, IFilesStorageProviderV60 provider, string directory, string action, UserInfo user) { if (user == null) { throw new ArgumentNullException("user"); } return(SetPermissionForDirectory(status, provider, directory, action, AuthTools.PrepareUsername(user.Username))); }
/// <summary> /// Sets a permission for a directory. /// </summary> /// <param name="status">The authorization status.</param> /// <param name="provider">The provider that handles the directory.</param> /// <param name="directory">The directory.</param> /// <param name="action">The action of which to modify the authorization status.</param> /// <param name="group">The group subject of the authorization change.</param> /// <returns><c>true</c> if the authorization status is changed, <c>false</c> otherwise.</returns> public bool SetPermissionForDirectory(AuthStatus status, IFilesStorageProviderV60 provider, string directory, string action, UserGroup group) { if (group == null) { throw new ArgumentNullException("group"); } return(SetPermissionForDirectory(status, provider, directory, action, AuthTools.PrepareGroup(group.Name))); }
/// <summary> /// Renames and re-indexes a page attachment. /// </summary> /// <param name="provider">The provider.</param> /// <param name="pageFullName">The page full name.</param> /// <param name="name">The attachment name.</param> /// <param name="newName">The new attachment name.</param> /// <returns><c>true</c> if the attachment was rename, <c>false</c> otherwise.</returns> public static bool RenamePageAttachment(IFilesStorageProviderV60 provider, string pageFullName, string name, string newName) { if (provider == null) { throw new ArgumentNullException("provider"); } if (pageFullName == null) { throw new ArgumentNullException("pageFullName"); } if (pageFullName.Length == 0) { throw new ArgumentException("Page Full Name cannot be empty", "pageFullName"); } if (name == null) { throw new ArgumentNullException("name"); } if (name.Length == 0) { throw new ArgumentException("Name cannot be empty", "name"); } if (newName == null) { throw new ArgumentNullException("newName"); } if (newName.Length == 0) { throw new ArgumentException("New Name cannot be empty", "newName"); } if (name.ToLowerInvariant() == newName.ToLowerInvariant()) { return(false); } PageContent page = Pages.FindPage(provider.CurrentWiki, pageFullName); if (page == null) { return(false); } bool done = provider.RenamePageAttachment(pageFullName, name, newName); if (!done) { return(false); } SearchClass.RenamePageAttachment(page, name, newName); Host.Instance.OnAttachmentActivity(provider.GetType().FullName, newName, pageFullName, name, FileActivity.AttachmentRenamed); return(true); }
/// <summary> /// Stores and indexes a file. /// </summary> /// <param name="provider">The destination provider.</param> /// <param name="fullName">The full name.</param> /// <param name="source">The source stream.</param> /// <param name="overwrite"><c>true</c> to overwrite the existing file, <c>false</c> otherwise.</param> /// <returns><c>true</c> if the file was stored, <c>false</c> otherwise.</returns> public static bool StoreFile(IFilesStorageProviderV60 provider, string fullName, Stream source, bool overwrite) { if (provider == null) { throw new ArgumentNullException("provider"); } if (fullName == null) { throw new ArgumentNullException("fullName"); } if (fullName.Length == 0) { throw new ArgumentException("Full Name cannot be empty", "fullName"); } if (source == null) { throw new ArgumentNullException("source"); } fullName = NormalizeFullName(fullName); bool done = provider.StoreFile(fullName, source, overwrite); if (!done) { return(false); } if (overwrite) { SearchClass.UnindexFile(provider.GetType().FullName + "|" + fullName, provider.CurrentWiki); } // Index the attached file string tempDir = Path.Combine(Environment.GetEnvironmentVariable("TEMP"), Guid.NewGuid().ToString()); if (!Directory.Exists(tempDir)) { Directory.CreateDirectory(tempDir); } string tempFile = Path.Combine(tempDir, Path.GetFileName(fullName)); source.Seek(0, SeekOrigin.Begin); using (FileStream temp = File.Create(tempFile)) { source.CopyTo(temp); } SearchClass.IndexFile(provider.GetType().FullName + "|" + fullName, tempFile, provider.CurrentWiki); Directory.Delete(tempDir, true); Host.Instance.OnFileActivity(provider.GetType().FullName, fullName, null, FileActivity.FileUploaded); return(true); }
/// <summary> /// Deletes the permissions of a directory. /// </summary> /// <param name="provider">The provider.</param> /// <param name="directory">The directory.</param> private static void DeletePermissions(IFilesStorageProviderV60 provider, string directory) { directory = NormalizeFullPath(directory); foreach (string sub in provider.ListDirectories(directory)) { DeletePermissions(provider, sub); } AuthWriter authWriter = new AuthWriter(Collectors.CollectorsBox.GetSettingsProvider(provider.CurrentWiki)); authWriter.ClearEntriesForDirectory(provider, directory); }
/// <summary> /// De-indexes all contents of a directory. /// </summary> /// <param name="provider">The provider.</param> /// <param name="directory">The directory.</param> private static void DeindexDirectory(IFilesStorageProviderV60 provider, string directory) { directory = NormalizeFullPath(directory); foreach (string sub in provider.ListDirectories(directory)) { DeindexDirectory(provider, sub); } foreach (string file in provider.ListFiles(directory)) { SearchClass.UnindexFile(provider.GetType().FullName + "|" + file, provider.CurrentWiki); } }
/// <summary> /// Renames and re-indexes a file. /// </summary> /// <param name="provider">The provider.</param> /// <param name="fullName">The full name of the file to rename.</param> /// <param name="newName">The new name of the file (without namespace).</param> /// <returns><c>true</c> if the file was renamed, <c>false</c> otherwise.</returns> public static bool RenameFile(IFilesStorageProviderV60 provider, string fullName, string newName) { if (provider == null) { throw new ArgumentNullException("provider"); } if (fullName == null) { throw new ArgumentNullException("fullName"); } if (fullName.Length == 0) { throw new ArgumentException("Full Name cannot be empty", "fullName"); } if (newName == null) { throw new ArgumentNullException("newName"); } if (newName.Length == 0) { throw new ArgumentException("New Name cannot be empty", "newName"); } fullName = NormalizeFullName(fullName); string newFullName = GetDirectory(fullName) + newName; newFullName = NormalizeFullName(newFullName); if (newFullName.ToLowerInvariant() == fullName.ToLowerInvariant()) { return(false); } bool done = provider.RenameFile(fullName, newFullName); if (!done) { return(false); } SearchClass.RenameFile(provider.CurrentWiki, provider.GetType().FullName + "|" + fullName, provider.GetType().FullName + "|" + newFullName); Host.Instance.OnFileActivity(provider.GetType().FullName, fullName, newFullName, FileActivity.FileRenamed); return(true); }
/// <summary> /// Gets the proper full name for a directory. /// </summary> /// <param name="prov">The provider.</param> /// <param name="name">The directory name.</param> /// <returns>The full name (<b>not</b> prepended with <see cref="Actions.ForDirectories.ResourceMasterPrefix" />.</returns> public static string GetDirectoryName(IFilesStorageProviderV60 prov, string name) { if (prov == null) { throw new ArgumentNullException("prov"); } if (name == null) { throw new ArgumentNullException("name"); } if (name.Length == 0) { throw new ArgumentException("Name cannot be empty", "name"); } return("(" + prov.GetType().FullName + ")" + name); }
/// <summary> /// Renames a directory and re-indexes all contents. /// </summary> /// <param name="provider">The provider.</param> /// <param name="fullPath">The full path of the directory to rename.</param> /// <param name="newName">The new name of the directory.</param> /// <returns><c>true</c> if the directory was renamed, <c>false</c> otherwise.</returns> public static bool RenameDirectory(IFilesStorageProviderV60 provider, string fullPath, string newName) { if (provider == null) { throw new ArgumentNullException("provider"); } if (fullPath == null) { throw new ArgumentNullException("fullPath"); } if (fullPath.Length == 0) { throw new ArgumentException("Cannot rename the root directory", "fullPath"); } if (newName == null) { throw new ArgumentNullException("newName"); } if (newName.Length == 0) { throw new ArgumentException("New Name cannot be empty", "newName"); } fullPath = NormalizeFullPath(fullPath); string newFullPath = GetDirectory(fullPath) + newName; newFullPath = NormalizeFullPath(newFullPath); bool done = provider.RenameDirectory(fullPath, newFullPath); if (!done) { return(false); } MovePermissions(provider, fullPath, newFullPath); ReindexDirectory(provider, fullPath, newFullPath); Host.Instance.OnDirectoryActivity(provider.GetType().FullName, fullPath, newFullPath, FileActivity.DirectoryRenamed); return(true); }
/// <summary> /// Clears all the ACL entries for a directory. /// </summary> /// <param name="provider">The provider.</param> /// <param name="directory">The directory.</param> public void ClearEntriesForDirectory(IFilesStorageProviderV60 provider, string directory) { if (provider == null) { throw new ArgumentNullException("provider"); } if (directory == null) { throw new ArgumentNullException("directory"); } if (directory.Length == 0) { throw new ArgumentException("Directory cannot be empty", "directory"); } string resourceName = Actions.ForDirectories.ResourceMasterPrefix + AuthTools.GetDirectoryName(provider, directory); _settingsProvider.AclManager.DeleteEntriesForResource(resourceName); }
/// <summary> /// Creates a new directory. /// </summary> /// <param name="provider">The provider.</param> /// <param name="path">The path.</param> /// <param name="name">The name of the new directory.</param> /// <returns><c>true</c> if the directory was created, <c>false</c> otherwise.</returns> public static bool CreateDirectory(IFilesStorageProviderV60 provider, string path, string name) { if (provider == null) { throw new ArgumentNullException("provider"); } if (path == null) { throw new ArgumentNullException("path"); } if (path.Length == 0) { path = "/"; } if (name == null) { throw new ArgumentNullException("name"); } if (name.Length == 0) { throw new ArgumentException("Name cannot be empty", "name"); } path = NormalizeFullPath(path); name = name.Trim('/', ' '); bool done = provider.CreateDirectory(path, name); if (!done) { return(false); } Host.Instance.OnDirectoryActivity(provider.GetType().FullName, path + name + "/", null, FileActivity.DirectoryCreated); return(true); }
/// <summary> /// Recursively moves permissions from the old (renamed) directory to the new one. /// </summary> /// <param name="provider">The provider.</param> /// <param name="oldDirectory">The old directory.</param> /// <param name="newDirectory">The new directory.</param> private static void MovePermissions(IFilesStorageProviderV60 provider, string oldDirectory, string newDirectory) { oldDirectory = NormalizeFullPath(oldDirectory); newDirectory = NormalizeFullPath(newDirectory); // At this point the directory has been already renamed, // thus we must list on the new directory and construct the old name // Example: /directory/one/ renamed to /directory/two-two/ // List on /directory/two-two/ // dir1 // dir2 // oldSub = /directory/one/dir1/ foreach (string sub in provider.ListDirectories(newDirectory)) { string oldSub = oldDirectory + sub.Substring(newDirectory.Length); MovePermissions(provider, oldSub, sub); } AuthWriter authWriter = new AuthWriter(Collectors.CollectorsBox.GetSettingsProvider(provider.CurrentWiki)); authWriter.ClearEntriesForDirectory(provider, newDirectory); authWriter.ProcessDirectoryRenaming(provider, oldDirectory, newDirectory); }
/// <summary> /// Initializes a new instance of the <see cref="T:StDirectoryInfo" /> class. /// </summary> /// <param name="fullPath">The full path of the directory, for example <b>/dir/sub/</b> or <b>/</b>.</param> /// <param name="provider">The provider that handles the directory.</param> public StDirectoryInfo(string fullPath, IFilesStorageProviderV60 provider) { this.fullPath = fullPath; this.provider = provider; }
/// <summary> /// Sets a permission for a directory. /// </summary> /// <param name="status">The authorization status.</param> /// <param name="provider">The provider that handles the directory.</param> /// <param name="directory">The directory.</param> /// <param name="action">The action of which to modify the authorization status.</param> /// <param name="subject">The subject of the authorization change.</param> /// <returns><c>true</c> if the authorization status is changed, <c>false</c> otherwise.</returns> private bool SetPermissionForDirectory(AuthStatus status, IFilesStorageProviderV60 provider, string directory, string action, string subject) { if (provider == null) { throw new ArgumentNullException("provider"); } if (directory == null) { throw new ArgumentNullException("directory"); } if (directory.Length == 0) { throw new ArgumentException("Directory cannot be empty", "directory"); } if (action == null) { throw new ArgumentNullException("action"); } if (action.Length == 0) { throw new ArgumentException("Action cannot be empty", "action"); } if (action != Actions.FullControl && !AuthTools.IsValidAction(action, Actions.ForDirectories.All)) { throw new ArgumentException("Invalid action", "action"); } string directoryName = AuthTools.GetDirectoryName(provider, directory); if (status == AuthStatus.Delete) { bool done = _settingsProvider.AclManager.DeleteEntry(Actions.ForDirectories.ResourceMasterPrefix + directoryName, action, subject); if (done) { Log.LogEntry(MessageDeleteSuccess + GetLogMessage(Actions.ForDirectories.ResourceMasterPrefix, directoryName, action, subject, Delete), EntryType.General, Log.SystemUsername, _settingsProvider.CurrentWiki); } else { Log.LogEntry(MessageDeleteFailure + GetLogMessage(Actions.ForDirectories.ResourceMasterPrefix, directoryName, action, subject, Delete), EntryType.Error, Log.SystemUsername, _settingsProvider.CurrentWiki); } return(done); } else { bool done = _settingsProvider.AclManager.StoreEntry(Actions.ForDirectories.ResourceMasterPrefix + directoryName, action, subject, status == AuthStatus.Grant ? Value.Grant : Value.Deny); if (done) { Log.LogEntry(MessageSetSuccess + GetLogMessage(Actions.ForDirectories.ResourceMasterPrefix, directoryName, action, subject, Set + status.ToString()), EntryType.General, Log.SystemUsername, _settingsProvider.CurrentWiki); } else { Log.LogEntry(MessageSetFailure + GetLogMessage(Actions.ForDirectories.ResourceMasterPrefix, directoryName, action, subject, Set + status.ToString()), EntryType.Error, Log.SystemUsername, _settingsProvider.CurrentWiki); } return(done); } }
/// <summary> /// Initializes a new instance of the <see cref="StFileInfo" /> class. /// </summary> /// <param name="details">The file details.</param> /// <param name="fullName">The full name.</param> /// <param name="provider">The provider.</param> public StFileInfo(FileDetails details, string fullName, IFilesStorageProviderV60 provider) : this(details.Size, details.LastModified, fullName, provider) { }
/// <summary> /// Initializes a new instance of the <see cref="T:StFileInfo" /> class. /// </summary> /// <param name="size">The size of the file in bytes.</param> /// <param name="lastModified">The last modification date/time.</param> /// <param name="fullName">The full name of the file, for example <b>/dir/sub/file.txt</b> or <b>/file.txt</b>.</param> /// <param name="provider">The provider that handles the file.</param> public StFileInfo(long size, DateTime lastModified, string fullName, IFilesStorageProviderV60 provider) : base(size, lastModified) { this.fullName = fullName; this.provider = provider; }
/// <summary> /// Checks whether an action is allowed for a directory. /// </summary> /// <param name="provider">The provider that manages the directory.</param> /// <param name="directory">The full path of the directory.</param> /// <param name="action">The action the user is attempting to perform.</param> /// <param name="currentUser">The current user.</param> /// <param name="groups">The groups the user is member of.</param> /// <returns><c>true</c> if the action is allowed, <c>false</c> otherwise.</returns> public bool CheckActionForDirectory(IFilesStorageProviderV60 provider, string directory, string action, string currentUser, string[] groups) { if (provider == null) { throw new ArgumentNullException("provider"); } if (directory == null) { throw new ArgumentNullException("directory"); } if (directory.Length == 0) { throw new ArgumentException("Directory cannot be empty", "directory"); } if (action == null) { throw new ArgumentNullException("action"); } if (action.Length == 0) { throw new ArgumentException("Action cannot be empty", "action"); } if (!AuthTools.IsValidAction(action, Actions.ForDirectories.All)) { throw new ArgumentException("Invalid action", "action"); } if (currentUser == null) { throw new ArgumentNullException("currentUser"); } if (currentUser.Length == 0) { throw new ArgumentException("Current User cannot be empty", "currentUser"); } if (groups == null) { throw new ArgumentNullException("groups"); } if (currentUser == "admin") { return(true); } string resourceName = Actions.ForDirectories.ResourceMasterPrefix + AuthTools.GetDirectoryName(provider, directory); AclEntry[] entries = _settingsProvider.AclManager.RetrieveEntriesForResource(resourceName); Authorization auth = AclEvaluator.AuthorizeAction(resourceName, action, AuthTools.PrepareUsername(currentUser), AuthTools.PrepareGroups(groups), entries); if (auth != Authorization.Unknown) { return(auth == Authorization.Granted); } // Try local escalators string[] localEscalators = null; if (Actions.ForDirectories.LocalEscalators.TryGetValue(action, out localEscalators)) { foreach (string localAction in localEscalators) { bool authorized = CheckActionForDirectory(provider, directory, localAction, currentUser, groups); if (authorized) { return(true); } } } // Try directory escalation (extract parent directory and check its permissions) // Path manipulation keeps the format used by the caller (leading and trailing slashes are preserved if appropriate) string trimmedDirectory = directory.Trim('/'); if (trimmedDirectory.Length > 0) { int slashIndex = trimmedDirectory.LastIndexOf('/'); string parentDir = ""; if (slashIndex > 0) { // Navigate one level up, using the same slash format as the current one parentDir = (directory.StartsWith("/") ? "/" : "") + trimmedDirectory.Substring(0, slashIndex) + (directory.EndsWith("/") ? "/" : ""); } else { // This is the root parentDir = directory.StartsWith("/") ? "/" : ""; } bool authorized = CheckActionForDirectory(provider, parentDir, action, currentUser, groups); if (authorized) { return(true); } } // Try global escalators string[] globalEscalators = null; if (Actions.ForDirectories.GlobalEscalators.TryGetValue(action, out globalEscalators)) { foreach (string globalAction in globalEscalators) { bool authorized = CheckActionForGlobals(globalAction, currentUser, groups); if (authorized) { return(true); } } } return(false); }