/// <summary> /// Creates a relative path to a resource regarding a given root. /// </summary> /// <param name="resource">The resource to be processed.</param> /// <param name="root">The root to be applied. Can be null.</param> /// <returns>Path to the resource, if possible relative to the root folder.</returns> /// <exception cref="ArgumentNullException">If <paramref name="resource"/> /// is a null reference.</exception> public static string GetRelativePath(this VirtualResourceInfo resource, DirectoryInfo root) { if (resource == null) { throw new ArgumentNullException("resource"); } return(GetRelativePath(resource.FullName, root)); }
/// <summary> /// Converts the <see cref="VirtualResourceInfo.FullName"/> property of a given /// resource into a shortened path that is relative to the submitted /// <paramref name="root"/> directory.<br/> /// If <paramref name="root"/> is null, the path remains unchanged. /// </summary> /// <param name="resource">The resource to be processed.</param> /// <param name="root">The root path, if any. Can be null.</param> /// <exception cref="ArgumentNullException">If <paramref name="resource"/> /// is a null reference.</exception> internal static void MakePathsRelativeTo(this VirtualResourceInfo resource, DirectoryInfo root) { if (resource == null) { throw new ArgumentNullException("resource"); } if (root == null) { return; } resource.FullName = resource.GetRelativePath(root); resource.ParentFolderPath = GetRelativePath(resource.ParentFolderPath, root); }
private static void SetCommonProperties(VirtualResourceInfo resourceInfo, ZipNode node) { resourceInfo.FullName = node.FullName; resourceInfo.ParentFolderPath = node.ParentNode == null ? null : node.ParentNode.FullName; var entry = node.FileEntry; if (entry != null) { resourceInfo.Description = entry.Info; resourceInfo.IsHidden = (entry.Attributes & FileAttributes.Hidden) == FileAttributes.Hidden; resourceInfo.IsReadOnly = (entry.Attributes & FileAttributes.ReadOnly) == FileAttributes.ReadOnly; resourceInfo.CreationTime = entry.CreationTime == DateTime.MinValue ? (DateTimeOffset?)null : entry.CreationTime.ToLocalTime(); resourceInfo.LastWriteTime = entry.LastModified == DateTime.MinValue ? (DateTimeOffset?)null : entry.LastModified.ToLocalTime(); } }
/// <summary> /// Resolves the parent folder for a virtual resource. /// </summary> /// <param name="child">The child file or folder.</param> /// <returns>The parent folder info.</returns> private VirtualFolderInfo GetParentInternal(VirtualResourceInfo child) { if (child == null) { throw new ArgumentNullException("child"); } string path = PathUtil.GetAbsolutePath(child.FullName, RootDirectory); if (IsRootPath(path)) { //only log the request for the root's parent - do not include that //info in an exception in case we're hiding path information string msg = "Error while requesting parent of resource {0} - the folder itself already is the root."; VfsLog.Error(msg, child.FullName); //create exception with a relative path, if required string exceptionPath = UseRelativePaths ? PathUtil.RelativeRootPrefix : child.FullName; msg = String.Format(msg, exceptionPath); throw new ResourceAccessException(msg); } //make sure the processed directory exists VirtualFolderInfo folder = child as VirtualFolderInfo; if (folder != null) { folder.VerifyDirectoryExists(RootDirectory); } else { VirtualFileInfo file = (VirtualFileInfo)child; file.VerifyFileExists(RootDirectory); } //get the path of the parent (returned value may be null!) string parentPath = Path.GetDirectoryName(path); //get folder info return(GetFolderInfo(parentPath)); }
/// <summary> /// Validates whether a <see cref="LocalFileSystemProvider"/> was configured /// with access restricted to a given <see cref="LocalFileSystemProvider.RootDirectory"/>, /// and makes sure that the requested <paramref name="resource"/> is indeed contained /// within that folder. /// </summary> /// <param name="resource">The requested resource.</param> /// <exception cref="ResourceAccessException">If the requested resource is not /// a descendant of a configured <see cref="LocalFileSystemProvider.RootDirectory"/>.</exception> /// <exception cref="ArgumentNullException">If <paramref name="resource"/> /// is a null reference.</exception> private void ValidateResourceAccess(VirtualResourceInfo resource) { if (resource == null) throw new ArgumentNullException("resource"); //if there isn't a restricted custom root, every file resource can be accessed //(if the path is invalid, this will fail later, depending on the action) if (RootDirectory == null) return; try { string path = PathUtil.GetAbsolutePath(resource.FullName, RootDirectory); //if the root path was submitted, we're within the scope, too if (IsRootPath(path)) return; //if we have a custom root, make sure the resource is indeed a descendant of the root if (RootDirectory.IsParentOf(path)) return; } catch(ResourceAccessException e) { //just bubble a resource access exception if (e.Resource == null) e.Resource = resource; throw; } catch (Exception e) { //exceptions can happen in case of invalid file paths //log detailed info string error = "Resource request for '{0}' caused exception when validating against root directory '{1}'."; error = String.Format(error, resource.FullName, RootDirectory.FullName); VfsLog.Debug(e, error); //do not expose too much path information (e.g. absolute paths if disabled) error = String.Format("Invalid resource path: '{0}'.", resource.FullName); throw new ResourceAccessException(error) { Resource = resource }; } //if none of the above is true, the request is invalid //log detailed info string msg = "Resource request for '{0}' was blocked. The resource is outside the root directory '{1}'."; msg = String.Format(msg, resource.FullName, RootDirectory.FullName); VfsLog.Debug(msg); //do not expose too much path information (e.g. absolute paths if disabled) msg = String.Format("Invalid resource path: '{0}'.", resource.FullName); throw new ResourceAccessException(msg) { Resource = resource }; }
/// <summary> /// Resolves the parent folder for a virtual resource. /// </summary> /// <param name="child">The child file or folder.</param> /// <returns>The parent folder info.</returns> private VirtualFolderInfo GetParentInternal(VirtualResourceInfo child) { if (child == null) throw new ArgumentNullException("child"); string path = PathUtil.GetAbsolutePath(child.FullName, RootDirectory); if (IsRootPath(path)) { //only log the request for the root's parent - do not include that //info in an exception in case we're hiding path information string msg = "Error while requesting parent of resource {0} - the folder itself already is the root."; VfsLog.Error(msg, child.FullName); //create exception with a relative path, if required string exceptionPath = UseRelativePaths ? PathUtil.RelativeRootPrefix : child.FullName; msg = String.Format(msg, exceptionPath); throw new ResourceAccessException(msg); } //make sure the processed directory exists VirtualFolderInfo folder = child as VirtualFolderInfo; if (folder != null) { folder.VerifyDirectoryExists(RootDirectory); } else { VirtualFileInfo file = (VirtualFileInfo) child; file.VerifyFileExists(RootDirectory); } //get the path of the parent (returned value may be null!) string parentPath = Path.GetDirectoryName(path); //get folder info return GetFolderInfo(parentPath); }
/// <summary> /// Validates whether a <see cref="LocalFileSystemProvider"/> was configured /// with access restricted to a given <see cref="LocalFileSystemProvider.RootDirectory"/>, /// and makes sure that the requested <paramref name="resource"/> is indeed contained /// within that folder. /// </summary> /// <param name="resource">The requested resource.</param> /// <exception cref="ResourceAccessException">If the requested resource is not /// a descendant of a configured <see cref="LocalFileSystemProvider.RootDirectory"/>.</exception> /// <exception cref="ArgumentNullException">If <paramref name="resource"/> /// is a null reference.</exception> private void ValidateResourceAccess(VirtualResourceInfo resource) { if (resource == null) { throw new ArgumentNullException("resource"); } //if there isn't a restricted custom root, every file resource can be accessed //(if the path is invalid, this will fail later, depending on the action) if (RootDirectory == null) { return; } try { string path = PathUtil.GetAbsolutePath(resource.FullName, RootDirectory); //if the root path was submitted, we're within the scope, too if (IsRootPath(path)) { return; } //if we have a custom root, make sure the resource is indeed a descendant of the root if (RootDirectory.IsParentOf(path)) { return; } } catch (ResourceAccessException e) { //just bubble a resource access exception if (e.Resource == null) { e.Resource = resource; } throw; } catch (Exception e) { //exceptions can happen in case of invalid file paths //log detailed info string error = "Resource request for '{0}' caused exception when validating against root directory '{1}'."; error = String.Format(error, resource.FullName, RootDirectory.FullName); VfsLog.Debug(e, error); //do not expose too much path information (e.g. absolute paths if disabled) error = String.Format("Invalid resource path: '{0}'.", resource.FullName); throw new ResourceAccessException(error) { Resource = resource }; } //if none of the above is true, the request is invalid //log detailed info string msg = "Resource request for '{0}' was blocked. The resource is outside the root directory '{1}'."; msg = String.Format(msg, resource.FullName, RootDirectory.FullName); VfsLog.Debug(msg); //do not expose too much path information (e.g. absolute paths if disabled) msg = String.Format("Invalid resource path: '{0}'.", resource.FullName); throw new ResourceAccessException(msg) { Resource = resource }; }