Files
FileShare_Website/Default.aspx.cs
T
2026-09-24 12:38:47 +00:00

1271 lines
30 KiB
C#

using System;
using System.Collections.Generic;
using System.IO;
using System.Security;
using System.Security.Principal;
using System.Text;
using System.Web;
using System.Web.UI;
namespace FileSharePortal
{
public partial class Default : Page
{
private const string ShareRoot =
@"\\LAN-DC1\Fileshare";
private static readonly Dictionary<string, string> RootFolders =
new Dictionary<string, string>(
StringComparer.OrdinalIgnoreCase)
{
{
"Free Trial Documents",
"Dokumente rund um Free Trials"
},
{
"Sales Ordner",
"Dokumente für den Vertrieb"
},
{
"Technical User Folder",
"Technische Dokumente und Unterlagen"
}
};
public string CurrentUser
{
get;
private set;
}
public string CurrentPath
{
get;
private set;
}
public string BreadcrumbHtml
{
get;
private set;
}
public string ContentHtml
{
get;
private set;
}
protected void Page_Load(
object sender,
EventArgs e)
{
Response.Cache.SetCacheability(
HttpCacheability.NoCache);
Response.Cache.SetNoStore();
CurrentUser =
WindowsIdentity.GetCurrent().Name;
string relativePath =
Request.QueryString["path"] ?? "";
try
{
string physicalPath =
GetSafePhysicalPath(
relativePath);
CurrentPath =
relativePath;
BreadcrumbHtml =
BuildBreadcrumb(
relativePath);
if (
string.IsNullOrEmpty(
relativePath))
{
ContentHtml =
BuildRootFolderList();
}
else
{
ContentHtml =
BuildDirectoryContents(
physicalPath,
relativePath);
}
}
catch (UnauthorizedAccessException)
{
ContentHtml =
BuildError(
"Zugriff verweigert",
"Sie haben keine Berechtigung auf diesen Bereich zuzugreifen.");
}
catch (DirectoryNotFoundException)
{
ContentHtml =
BuildError(
"Ordner nicht gefunden",
"Der angeforderte Ordner existiert nicht.");
}
catch (SecurityException)
{
ContentHtml =
BuildError(
"Ungültiger Pfad",
"Der angeforderte Pfad ist nicht zulässig.");
}
catch
{
ContentHtml =
BuildError(
"Fehler",
"Der angeforderte Bereich konnte nicht geladen werden.");
}
}
/*
* ========================================================
* ORDNER-ICON
* ========================================================
*/
private string FolderIconSvg()
{
return @"
<svg
viewBox=""0 0 24 24""
xmlns=""http://www.w3.org/2000/svg""
aria-hidden=""true"">
<path
d=""M3 6.5C3 5.67 3.67 5 4.5 5H9L11 7H19.5C20.33 7 21 7.67 21 8.5V18.5C21 19.33 20.33 20 19.5 20H4.5C3.67 20 3 19.33 3 18.5V6.5Z""
fill=""none""
stroke=""currentColor""
stroke-width=""1.8""
stroke-linejoin=""round"" />
</svg>";
}
/*
* ========================================================
* DATEI-ICON
* ========================================================
*/
private string FileIconSvg(
string extension)
{
string label =
"FILE";
string fill =
"#6b7280";
switch (extension)
{
case ".pdf":
label = "PDF";
fill = "#dc2626";
break;
case ".doc":
case ".docx":
label = "WORD";
fill = "#2563eb";
break;
case ".xls":
case ".xlsx":
case ".xlsm":
label = "XLS";
fill = "#16a34a";
break;
case ".ppt":
case ".pptx":
label = "PPT";
fill = "#ea580c";
break;
case ".zip":
case ".7z":
case ".rar":
case ".tar":
case ".gz":
label = "ZIP";
fill = "#7c3aed";
break;
case ".jpg":
case ".jpeg":
case ".png":
case ".gif":
case ".webp":
case ".bmp":
label = "IMG";
fill = "#0891b2";
break;
case ".mp3":
case ".wav":
case ".ogg":
label = "AUDIO";
fill = "#c026d3";
break;
case ".mp4":
case ".webm":
case ".ogv":
label = "VIDEO";
fill = "#9333ea";
break;
case ".txt":
case ".log":
case ".csv":
case ".json":
case ".xml":
label = "TXT";
fill = "#64748b";
break;
case ".exe":
case ".msi":
label = "APP";
fill = "#475569";
break;
default:
label = "FILE";
fill = "#6b7280";
break;
}
return
"<svg " +
"viewBox=\"0 0 64 64\" " +
"xmlns=\"http://www.w3.org/2000/svg\" " +
"aria-hidden=\"true\">" +
"<path " +
"d=\"M14 6H38L50 18V56H14Z\" " +
"fill=\"#ffffff\" " +
"stroke=\"" + fill + "\" " +
"stroke-width=\"3\" " +
"stroke-linejoin=\"round\" />" +
"<path " +
"d=\"M38 6V18H50\" " +
"fill=\"none\" " +
"stroke=\"" + fill + "\" " +
"stroke-width=\"3\" " +
"stroke-linejoin=\"round\" />" +
"<rect " +
"x=\"10\" " +
"y=\"38\" " +
"width=\"44\" " +
"height=\"15\" " +
"rx=\"4\" " +
"fill=\"" + fill + "\" />" +
"<text " +
"x=\"32\" " +
"y=\"49\" " +
"text-anchor=\"middle\" " +
"font-family=\"Arial, sans-serif\" " +
"font-size=\"8\" " +
"font-weight=\"700\" " +
"fill=\"#ffffff\">" +
HttpUtility.HtmlEncode(label) +
"</text>" +
"</svg>";
}
/*
* ========================================================
* STARTSEITE
* ========================================================
*/
private string BuildRootFolderList()
{
var html =
new StringBuilder();
html.Append(
"<div class=\"folder-grid\">"
);
int visibleFolders = 0;
foreach (
KeyValuePair<string, string> folder
in RootFolders)
{
string folderName =
folder.Key;
string path =
Path.Combine(
ShareRoot,
folderName);
if (!Directory.Exists(path))
continue;
if (!CanBrowseDirectory(path))
continue;
visibleFolders++;
string encodedPath =
HttpUtility.UrlEncode(
folderName);
html.Append(
"<a class=\"folder-card\" href=\"?path=" +
HttpUtility.HtmlAttributeEncode(
encodedPath) +
"\">"
);
html.Append(
"<div class=\"folder-icon\">"
);
html.Append(
FolderIconSvg()
);
html.Append(
"</div>"
);
html.Append(
"<div class=\"folder-content\">"
);
html.Append(
"<div class=\"folder-title\">" +
HttpUtility.HtmlEncode(
folderName) +
"</div>"
);
html.Append(
"<div class=\"folder-description\">" +
HttpUtility.HtmlEncode(
folder.Value) +
"</div>"
);
html.Append(
"</div>"
);
html.Append(
"<div class=\"folder-arrow\">→</div>"
);
html.Append(
"</a>"
);
}
html.Append(
"</div>"
);
if (visibleFolders == 0)
{
return BuildError(
"Keine Bereiche verfügbar",
"Für Ihr Benutzerkonto wurden keine zugänglichen Bereiche gefunden.");
}
return html.ToString();
}
/*
* ========================================================
* VERZEICHNISINHALT
* ========================================================
*/
private string BuildDirectoryContents(
string physicalPath,
string relativePath)
{
var html =
new StringBuilder();
/*
* ZURÜCK
*/
html.Append(
"<div class=\"toolbar\">"
);
string parentPath =
GetParentRelativePath(
relativePath);
if (parentPath != null)
{
if (
string.IsNullOrEmpty(
parentPath))
{
html.Append(
"<a class=\"back-button\" href=\"./\">" +
"← Startseite" +
"</a>"
);
}
else
{
html.Append(
"<a class=\"back-button\" href=\"?path=" +
HttpUtility.HtmlAttributeEncode(
HttpUtility.UrlEncode(
parentPath)) +
"\">" +
"← Zurück" +
"</a>"
);
}
}
html.Append(
"</div>"
);
var itemHtml =
new StringBuilder();
/*
* ====================================================
* UNTERORDNER
* ====================================================
*/
string[] directories =
Directory.GetDirectories(
physicalPath);
foreach (
string directory
in directories)
{
if (!CanBrowseDirectory(directory))
continue;
string directoryName =
Path.GetFileName(directory);
string childRelativePath =
CombineRelativePath(
relativePath,
directoryName);
itemHtml.Append(
"<a class=\"item\" href=\"?path=" +
HttpUtility.HtmlAttributeEncode(
HttpUtility.UrlEncode(
childRelativePath)) +
"\">"
);
itemHtml.Append(
"<div class=\"item-icon\">"
);
itemHtml.Append(
FolderIconSvg()
);
itemHtml.Append(
"</div>"
);
itemHtml.Append(
"<div class=\"item-name\">" +
HttpUtility.HtmlEncode(
directoryName) +
"</div>"
);
itemHtml.Append(
"<div class=\"item-arrow\">→</div>"
);
itemHtml.Append(
"</a>"
);
}
/*
* ====================================================
* DATEIEN
* ====================================================
*/
string[] files =
Directory.GetFiles(
physicalPath);
foreach (
string file
in files)
{
/*
* Eine Datei muss tatsächlich gelesen werden
* können. So erscheinen keine Dateien, auf die
* der Benutzer keine Leseberechtigung hat.
*/
if (!CanReadFile(file))
continue;
string fileName =
Path.GetFileName(file);
string extension =
Path.GetExtension(file)
.ToLowerInvariant();
FileInfo info =
new FileInfo(file);
string fileRelativePath =
CombineRelativePath(
relativePath,
fileName);
string viewUrl =
"View.aspx?path=" +
HttpUtility.UrlEncode(
fileRelativePath);
string downloadUrl =
"Download.aspx?path=" +
HttpUtility.UrlEncode(
fileRelativePath);
/*
* Dateizeile
*/
itemHtml.Append(
"<div class=\"file-row\">"
);
/*
* Klickbarer Dateibereich
*/
itemHtml.Append(
"<a class=\"file-main\" href=\"" +
HttpUtility.HtmlAttributeEncode(
viewUrl) +
"\">"
);
itemHtml.Append(
"<div class=\"item-icon\">"
);
itemHtml.Append(
FileIconSvg(
extension)
);
itemHtml.Append(
"</div>"
);
itemHtml.Append(
"<div class=\"file-info\">"
);
itemHtml.Append(
"<div class=\"file-name\">" +
HttpUtility.HtmlEncode(
fileName) +
"</div>"
);
itemHtml.Append(
"<div class=\"file-details\">" +
HttpUtility.HtmlEncode(
GetFileTypeDescription(
extension)) +
" &nbsp;·&nbsp; " +
FormatFileSize(
info.Length) +
" &nbsp;·&nbsp; " +
info.LastWriteTime.ToString(
"dd.MM.yyyy HH:mm") +
"</div>"
);
itemHtml.Append(
"</div>"
);
itemHtml.Append(
"</a>"
);
/*
* Separater Download-Button
*/
itemHtml.Append(
"<a class=\"download\" href=\"" +
HttpUtility.HtmlAttributeEncode(
downloadUrl) +
"\">" +
"Download" +
"</a>"
);
itemHtml.Append(
"</div>"
);
}
if (itemHtml.Length == 0)
{
html.Append(
"<div class=\"empty\">" +
"Dieser Ordner enthält keine für Sie sichtbaren Dateien oder Ordner." +
"</div>"
);
return html.ToString();
}
html.Append(
"<div class=\"item-list\">"
);
html.Append(
itemHtml.ToString()
);
html.Append(
"</div>"
);
return html.ToString();
}
/*
* ========================================================
* DATEILESEBERECHTIGUNG
* ========================================================
*/
private bool CanReadFile(
string path)
{
try
{
using (
FileStream stream =
new FileStream(
path,
FileMode.Open,
FileAccess.Read,
FileShare.ReadWrite |
FileShare.Delete))
{
}
return true;
}
catch
{
return false;
}
}
/*
* ========================================================
* DATEITYP BESCHREIBUNG
* ========================================================
*/
private string GetFileTypeDescription(
string extension)
{
switch (extension)
{
case ".pdf":
return "PDF-Dokument";
case ".doc":
case ".docx":
return "Word-Dokument";
case ".xls":
case ".xlsx":
case ".xlsm":
return "Excel-Tabelle";
case ".ppt":
case ".pptx":
return "PowerPoint-Präsentation";
case ".jpg":
case ".jpeg":
case ".png":
case ".gif":
case ".webp":
case ".bmp":
return "Bild";
case ".mp3":
case ".wav":
case ".ogg":
return "Audiodatei";
case ".mp4":
case ".webm":
case ".ogv":
return "Videodatei";
case ".txt":
return "Textdatei";
case ".csv":
return "CSV-Datei";
case ".json":
return "JSON-Datei";
case ".xml":
return "XML-Datei";
case ".log":
return "Logdatei";
case ".zip":
case ".7z":
case ".rar":
case ".tar":
case ".gz":
return "Archiv";
case ".exe":
return "Anwendung";
case ".msi":
return "Installationspaket";
default:
if (
string.IsNullOrEmpty(
extension))
{
return "Datei";
}
return
extension
.TrimStart('.')
.ToUpperInvariant();
}
}
/*
* ========================================================
* BREADCRUMB
* ========================================================
*/
private string BuildBreadcrumb(
string relativePath)
{
var html =
new StringBuilder();
html.Append(
"<div class=\"breadcrumb\">"
);
html.Append(
"<a href=\"./\">FileShare</a>"
);
if (
!string.IsNullOrEmpty(
relativePath))
{
string[] parts =
relativePath.Split(
new[] { '\\' },
StringSplitOptions.RemoveEmptyEntries);
string accumulated =
"";
for (
int i = 0;
i < parts.Length;
i++)
{
accumulated =
CombineRelativePath(
accumulated,
parts[i]);
html.Append(
"<span>/</span>"
);
if (
i ==
parts.Length - 1)
{
html.Append(
"<strong>" +
HttpUtility.HtmlEncode(
parts[i]) +
"</strong>"
);
}
else
{
html.Append(
"<a href=\"?path=" +
HttpUtility.HtmlAttributeEncode(
HttpUtility.UrlEncode(
accumulated)) +
"\">" +
HttpUtility.HtmlEncode(
parts[i]) +
"</a>"
);
}
}
}
html.Append(
"</div>"
);
return html.ToString();
}
/*
* ========================================================
* BERECHTIGUNG ORDNERVERZEICHNIS
* ========================================================
*/
private bool CanBrowseDirectory(
string path)
{
try
{
using (
var enumerator =
Directory
.EnumerateFileSystemEntries(
path)
.GetEnumerator())
{
enumerator.MoveNext();
}
return true;
}
catch
{
return false;
}
}
/*
* ========================================================
* SICHEREN ORDNERPFAD ERMITTELN
* ========================================================
*/
private string GetSafePhysicalPath(
string relativePath)
{
if (
string.IsNullOrWhiteSpace(
relativePath))
{
return ShareRoot;
}
string decoded =
HttpUtility.UrlDecode(
relativePath);
decoded =
decoded.Replace(
'/',
'\\');
if (
decoded.StartsWith("\\") ||
decoded.Contains(":"))
{
throw new SecurityException();
}
string[] parts =
decoded.Split(
new[] { '\\' },
StringSplitOptions.RemoveEmptyEntries);
foreach (
string part
in parts)
{
if (
part == "." ||
part == "..")
{
throw new SecurityException();
}
}
string fullPath =
Path.GetFullPath(
Path.Combine(
ShareRoot,
decoded));
string normalizedRoot =
Path.GetFullPath(
ShareRoot)
.TrimEnd('\\') +
"\\";
if (
!fullPath.StartsWith(
normalizedRoot,
StringComparison.OrdinalIgnoreCase))
{
throw new SecurityException();
}
if (
!Directory.Exists(
fullPath))
{
throw new DirectoryNotFoundException();
}
if (!CanBrowseDirectory(fullPath))
{
throw new UnauthorizedAccessException();
}
return fullPath;
}
/*
* ========================================================
* PARENT
* ========================================================
*/
private string GetParentRelativePath(
string path)
{
if (
string.IsNullOrEmpty(
path))
{
return null;
}
int position =
path.LastIndexOf('\\');
if (position < 0)
{
return "";
}
return path.Substring(
0,
position);
}
/*
* ========================================================
* RELATIVEN PFAD ZUSAMMENBAUEN
* ========================================================
*/
private string CombineRelativePath(
string parent,
string child)
{
if (
string.IsNullOrEmpty(
parent))
{
return child;
}
return
parent.TrimEnd('\\') +
"\\" +
child;
}
/*
* ========================================================
* DATEIGRÖSSE
* ========================================================
*/
private string FormatFileSize(
long bytes)
{
if (bytes < 1024)
{
return bytes + " B";
}
if (bytes < 1024 * 1024)
{
return
(bytes / 1024.0)
.ToString("0.0") +
" KB";
}
if (
bytes <
1024L * 1024L * 1024L)
{
return
(bytes /
1024.0 /
1024.0)
.ToString("0.0") +
" MB";
}
return
(bytes /
1024.0 /
1024.0 /
1024.0)
.ToString("0.0") +
" GB";
}
/*
* ========================================================
* FEHLER
* ========================================================
*/
private string BuildError(
string title,
string message)
{
return
"<div class=\"error\">" +
"<h3>" +
HttpUtility.HtmlEncode(
title) +
"</h3>" +
"<p>" +
HttpUtility.HtmlEncode(
message) +
"</p>" +
"</div>";
}
}
}