Dateien nach "/" hochladen
This commit is contained in:
commit
a50893a9b3
4 files changed
+2584
No files matched your search
+963
@@ -0,0 +1,963 @@
|
|||||||
|
<%@ Page
|
||||||
|
Language="C#"
|
||||||
|
ResponseEncoding="utf-8"
|
||||||
|
ContentType="text/html; charset=utf-8"
|
||||||
|
AutoEventWireup="true"
|
||||||
|
CodeFile="Default.aspx.cs"
|
||||||
|
Inherits="FileSharePortal.Default"
|
||||||
|
%>
|
||||||
|
|
||||||
|
<!DOCTYPE html>
|
||||||
|
|
||||||
|
<html lang="de">
|
||||||
|
|
||||||
|
<head runat="server">
|
||||||
|
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
|
||||||
|
<meta
|
||||||
|
name="viewport"
|
||||||
|
content="width=device-width, initial-scale=1" />
|
||||||
|
|
||||||
|
<title>FileShare</title>
|
||||||
|
|
||||||
|
|
||||||
|
<style>
|
||||||
|
|
||||||
|
/*
|
||||||
|
============================================================
|
||||||
|
GRUNDLAYOUT
|
||||||
|
============================================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
* {
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
html,
|
||||||
|
body {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
|
||||||
|
font-family:
|
||||||
|
"Segoe UI",
|
||||||
|
Arial,
|
||||||
|
Helvetica,
|
||||||
|
sans-serif;
|
||||||
|
|
||||||
|
background: #f3f4f6;
|
||||||
|
|
||||||
|
color: #1f2937;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
============================================================
|
||||||
|
HEADER
|
||||||
|
============================================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
.header {
|
||||||
|
background: #1f2937;
|
||||||
|
|
||||||
|
color: white;
|
||||||
|
|
||||||
|
padding: 26px 20px;
|
||||||
|
|
||||||
|
box-shadow:
|
||||||
|
0 2px 8px rgba(0, 0, 0, 0.15);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.header-inner {
|
||||||
|
max-width: 1050px;
|
||||||
|
|
||||||
|
margin: 0 auto;
|
||||||
|
|
||||||
|
display: flex;
|
||||||
|
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
gap: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.brand-icon {
|
||||||
|
width: 54px;
|
||||||
|
height: 54px;
|
||||||
|
|
||||||
|
flex-shrink: 0;
|
||||||
|
|
||||||
|
display: flex;
|
||||||
|
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
|
||||||
|
background: #374151;
|
||||||
|
|
||||||
|
border-radius: 12px;
|
||||||
|
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.brand-icon svg {
|
||||||
|
width: 29px;
|
||||||
|
height: 29px;
|
||||||
|
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.header-info {
|
||||||
|
min-width: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.header-info h1 {
|
||||||
|
margin: 0;
|
||||||
|
|
||||||
|
font-size: 27px;
|
||||||
|
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.header-info p {
|
||||||
|
margin: 4px 0 0;
|
||||||
|
|
||||||
|
color: #d1d5db;
|
||||||
|
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.user {
|
||||||
|
margin-left: auto;
|
||||||
|
|
||||||
|
color: #d1d5db;
|
||||||
|
|
||||||
|
font-size: 13px;
|
||||||
|
|
||||||
|
text-align: right;
|
||||||
|
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.user strong {
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
============================================================
|
||||||
|
HAUPTINHALT
|
||||||
|
============================================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
.content {
|
||||||
|
max-width: 1050px;
|
||||||
|
|
||||||
|
margin: 0 auto;
|
||||||
|
|
||||||
|
padding: 38px 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
============================================================
|
||||||
|
BREADCRUMB
|
||||||
|
============================================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
.breadcrumb {
|
||||||
|
margin-bottom: 25px;
|
||||||
|
|
||||||
|
color: #6b7280;
|
||||||
|
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.breadcrumb a {
|
||||||
|
color: #374151;
|
||||||
|
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.breadcrumb a:hover {
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.breadcrumb span {
|
||||||
|
margin: 0 6px;
|
||||||
|
|
||||||
|
color: #9ca3af;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.breadcrumb strong {
|
||||||
|
color: #1f2937;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
============================================================
|
||||||
|
EINLEITUNG
|
||||||
|
============================================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
.intro {
|
||||||
|
margin-bottom: 25px;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.intro h2 {
|
||||||
|
margin: 0 0 8px;
|
||||||
|
|
||||||
|
font-size: 27px;
|
||||||
|
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.intro p {
|
||||||
|
margin: 0;
|
||||||
|
|
||||||
|
color: #6b7280;
|
||||||
|
|
||||||
|
font-size: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
============================================================
|
||||||
|
ROOT-ORDNER
|
||||||
|
============================================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
.folder-grid {
|
||||||
|
display: grid;
|
||||||
|
|
||||||
|
grid-template-columns:
|
||||||
|
repeat(
|
||||||
|
auto-fit,
|
||||||
|
minmax(310px, 1fr)
|
||||||
|
);
|
||||||
|
|
||||||
|
gap: 18px;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.folder-card {
|
||||||
|
display: flex;
|
||||||
|
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
gap: 17px;
|
||||||
|
|
||||||
|
padding: 21px;
|
||||||
|
|
||||||
|
background: white;
|
||||||
|
|
||||||
|
border:
|
||||||
|
1px solid #e5e7eb;
|
||||||
|
|
||||||
|
border-radius: 14px;
|
||||||
|
|
||||||
|
color: inherit;
|
||||||
|
|
||||||
|
text-decoration: none;
|
||||||
|
|
||||||
|
transition:
|
||||||
|
transform 0.15s ease,
|
||||||
|
box-shadow 0.15s ease,
|
||||||
|
border-color 0.15s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.folder-card:hover {
|
||||||
|
transform: translateY(-2px);
|
||||||
|
|
||||||
|
border-color: #d1d5db;
|
||||||
|
|
||||||
|
box-shadow:
|
||||||
|
0 8px 22px
|
||||||
|
rgba(0, 0, 0, 0.08);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
============================================================
|
||||||
|
ORDNER-ICONS
|
||||||
|
============================================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
.folder-icon,
|
||||||
|
.item-icon {
|
||||||
|
width: 50px;
|
||||||
|
height: 50px;
|
||||||
|
|
||||||
|
flex-shrink: 0;
|
||||||
|
|
||||||
|
display: flex;
|
||||||
|
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
|
||||||
|
border-radius: 11px;
|
||||||
|
|
||||||
|
background: #f3f4f6;
|
||||||
|
|
||||||
|
color: #4b5563;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.folder-icon svg,
|
||||||
|
.item-icon svg {
|
||||||
|
width: 26px;
|
||||||
|
height: 26px;
|
||||||
|
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
============================================================
|
||||||
|
ORDNERINFORMATION
|
||||||
|
============================================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
.folder-content {
|
||||||
|
flex: 1;
|
||||||
|
|
||||||
|
min-width: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.folder-title {
|
||||||
|
margin-bottom: 5px;
|
||||||
|
|
||||||
|
font-size: 17px;
|
||||||
|
|
||||||
|
font-weight: 600;
|
||||||
|
|
||||||
|
overflow-wrap: anywhere;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.folder-description {
|
||||||
|
color: #6b7280;
|
||||||
|
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.folder-arrow,
|
||||||
|
.item-arrow {
|
||||||
|
color: #9ca3af;
|
||||||
|
|
||||||
|
font-size: 21px;
|
||||||
|
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
============================================================
|
||||||
|
ZURÜCK-BUTTON
|
||||||
|
============================================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
.toolbar {
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.back-button {
|
||||||
|
display: inline-block;
|
||||||
|
|
||||||
|
padding:
|
||||||
|
10px 15px;
|
||||||
|
|
||||||
|
background: white;
|
||||||
|
|
||||||
|
border:
|
||||||
|
1px solid #e5e7eb;
|
||||||
|
|
||||||
|
border-radius: 9px;
|
||||||
|
|
||||||
|
color: #374151;
|
||||||
|
|
||||||
|
text-decoration: none;
|
||||||
|
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.back-button:hover {
|
||||||
|
background: #f9fafb;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
============================================================
|
||||||
|
DATEILISTE
|
||||||
|
============================================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
.item-list {
|
||||||
|
background: white;
|
||||||
|
|
||||||
|
border:
|
||||||
|
1px solid #e5e7eb;
|
||||||
|
|
||||||
|
border-radius: 12px;
|
||||||
|
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
|
box-shadow:
|
||||||
|
0 2px 5px
|
||||||
|
rgba(0, 0, 0, 0.03);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Eine Datei bzw. ein Ordner = genau eine Zeile.
|
||||||
|
*/
|
||||||
|
|
||||||
|
.item {
|
||||||
|
display: flex;
|
||||||
|
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
min-height: 70px;
|
||||||
|
|
||||||
|
padding:
|
||||||
|
9px 16px;
|
||||||
|
|
||||||
|
background: white;
|
||||||
|
|
||||||
|
border-bottom:
|
||||||
|
1px solid #f0f0f0;
|
||||||
|
|
||||||
|
color: inherit;
|
||||||
|
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.item:last-child {
|
||||||
|
border-bottom: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.item:hover {
|
||||||
|
background: #fafafa;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
============================================================
|
||||||
|
ORDNERZEILE
|
||||||
|
============================================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
.item .item-name {
|
||||||
|
flex: 1;
|
||||||
|
|
||||||
|
min-width: 0;
|
||||||
|
|
||||||
|
padding-left: 15px;
|
||||||
|
|
||||||
|
font-size: 15px;
|
||||||
|
|
||||||
|
overflow-wrap: anywhere;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
============================================================
|
||||||
|
DATEIZEILE
|
||||||
|
============================================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
.file-row {
|
||||||
|
display: flex;
|
||||||
|
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
min-height: 70px;
|
||||||
|
|
||||||
|
padding:
|
||||||
|
8px 16px;
|
||||||
|
|
||||||
|
background: white;
|
||||||
|
|
||||||
|
border-bottom:
|
||||||
|
1px solid #f0f0f0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.file-row:last-child {
|
||||||
|
border-bottom: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.file-row:hover {
|
||||||
|
background: #fafafa;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Der linke Bereich umfasst Icon + Dateiname +
|
||||||
|
Zusatzinformationen.
|
||||||
|
*/
|
||||||
|
|
||||||
|
.file-main {
|
||||||
|
flex: 1;
|
||||||
|
|
||||||
|
min-width: 0;
|
||||||
|
|
||||||
|
display: flex;
|
||||||
|
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
gap: 14px;
|
||||||
|
|
||||||
|
color: inherit;
|
||||||
|
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.file-main:hover {
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.file-main:hover .file-name {
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
============================================================
|
||||||
|
DATEI-ICON
|
||||||
|
============================================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
.file-row .item-icon {
|
||||||
|
width: 48px;
|
||||||
|
height: 48px;
|
||||||
|
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.file-row .item-icon svg {
|
||||||
|
width: 27px;
|
||||||
|
height: 27px;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
============================================================
|
||||||
|
DATEIINFORMATION
|
||||||
|
============================================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
.file-info {
|
||||||
|
flex: 1;
|
||||||
|
|
||||||
|
min-width: 0;
|
||||||
|
|
||||||
|
display: flex;
|
||||||
|
|
||||||
|
align-items: baseline;
|
||||||
|
|
||||||
|
gap: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.file-name {
|
||||||
|
min-width: 0;
|
||||||
|
|
||||||
|
color: #1f2937;
|
||||||
|
|
||||||
|
font-size: 15px;
|
||||||
|
|
||||||
|
font-weight: 500;
|
||||||
|
|
||||||
|
overflow-wrap: anywhere;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.file-details {
|
||||||
|
flex-shrink: 0;
|
||||||
|
|
||||||
|
color: #9ca3af;
|
||||||
|
|
||||||
|
font-size: 12px;
|
||||||
|
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
============================================================
|
||||||
|
DOWNLOAD-BUTTON
|
||||||
|
============================================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
.download {
|
||||||
|
display: inline-flex;
|
||||||
|
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
|
||||||
|
flex-shrink: 0;
|
||||||
|
|
||||||
|
margin-left: 18px;
|
||||||
|
|
||||||
|
min-width: 95px;
|
||||||
|
|
||||||
|
padding:
|
||||||
|
8px 13px;
|
||||||
|
|
||||||
|
background: #f3f4f6;
|
||||||
|
|
||||||
|
border:
|
||||||
|
1px solid #e5e7eb;
|
||||||
|
|
||||||
|
border-radius: 8px;
|
||||||
|
|
||||||
|
color: #374151;
|
||||||
|
|
||||||
|
font-size: 13px;
|
||||||
|
|
||||||
|
text-decoration: none;
|
||||||
|
|
||||||
|
transition:
|
||||||
|
background 0.15s ease,
|
||||||
|
border-color 0.15s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.download:hover {
|
||||||
|
background: #e5e7eb;
|
||||||
|
|
||||||
|
border-color: #d1d5db;
|
||||||
|
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
============================================================
|
||||||
|
LEERER ORDNER
|
||||||
|
============================================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
.empty {
|
||||||
|
background: white;
|
||||||
|
|
||||||
|
border:
|
||||||
|
1px solid #e5e7eb;
|
||||||
|
|
||||||
|
border-radius: 12px;
|
||||||
|
|
||||||
|
padding: 30px;
|
||||||
|
|
||||||
|
color: #6b7280;
|
||||||
|
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
============================================================
|
||||||
|
FEHLER
|
||||||
|
============================================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
.error {
|
||||||
|
background: white;
|
||||||
|
|
||||||
|
border:
|
||||||
|
1px solid #e5e7eb;
|
||||||
|
|
||||||
|
border-radius: 12px;
|
||||||
|
|
||||||
|
padding: 25px;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.error h3 {
|
||||||
|
margin:
|
||||||
|
0 0 7px;
|
||||||
|
|
||||||
|
font-size: 19px;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.error p {
|
||||||
|
margin: 0;
|
||||||
|
|
||||||
|
color: #6b7280;
|
||||||
|
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
============================================================
|
||||||
|
FOOTER
|
||||||
|
============================================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
.footer {
|
||||||
|
max-width: 1050px;
|
||||||
|
|
||||||
|
margin: 0 auto;
|
||||||
|
|
||||||
|
padding:
|
||||||
|
20px;
|
||||||
|
|
||||||
|
color: #9ca3af;
|
||||||
|
|
||||||
|
font-size: 13px;
|
||||||
|
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
============================================================
|
||||||
|
RESPONSIVE
|
||||||
|
============================================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
@media (max-width: 800px) {
|
||||||
|
|
||||||
|
.file-info {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.file-details {
|
||||||
|
display: block;
|
||||||
|
|
||||||
|
margin-top: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@media (max-width: 650px) {
|
||||||
|
|
||||||
|
.header-inner {
|
||||||
|
align-items: flex-start;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.user {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.folder-grid {
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.content {
|
||||||
|
padding:
|
||||||
|
28px 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.file-row {
|
||||||
|
min-height: 65px;
|
||||||
|
|
||||||
|
padding:
|
||||||
|
7px 11px;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.file-main {
|
||||||
|
gap: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.file-row .item-icon {
|
||||||
|
width: 42px;
|
||||||
|
height: 42px;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.file-row .item-icon svg {
|
||||||
|
width: 24px;
|
||||||
|
height: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.file-info {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.file-name {
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.file-details {
|
||||||
|
margin-top: 3px;
|
||||||
|
|
||||||
|
font-size: 11px;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.download {
|
||||||
|
min-width: auto;
|
||||||
|
|
||||||
|
margin-left: 8px;
|
||||||
|
|
||||||
|
padding:
|
||||||
|
7px 9px;
|
||||||
|
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
|
|
||||||
|
</head>
|
||||||
|
|
||||||
|
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<form
|
||||||
|
id="form1"
|
||||||
|
runat="server">
|
||||||
|
|
||||||
|
|
||||||
|
<!-- ========================================================
|
||||||
|
HEADER
|
||||||
|
======================================================== -->
|
||||||
|
|
||||||
|
<header class="header">
|
||||||
|
|
||||||
|
<div class="header-inner">
|
||||||
|
|
||||||
|
|
||||||
|
<div class="brand-icon">
|
||||||
|
|
||||||
|
<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>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<div class="header-info">
|
||||||
|
|
||||||
|
<h1>
|
||||||
|
FileShare
|
||||||
|
</h1>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Interne Dokumentenablage
|
||||||
|
</p>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<div class="user">
|
||||||
|
|
||||||
|
Angemeldet als:
|
||||||
|
|
||||||
|
<strong>
|
||||||
|
<%= Server.HtmlEncode(CurrentUser) %>
|
||||||
|
</strong>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</header>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- ========================================================
|
||||||
|
CONTENT
|
||||||
|
======================================================== -->
|
||||||
|
|
||||||
|
<main class="content">
|
||||||
|
|
||||||
|
|
||||||
|
<%= BreadcrumbHtml %>
|
||||||
|
|
||||||
|
|
||||||
|
<div class="intro">
|
||||||
|
|
||||||
|
<h2>
|
||||||
|
<%= string.IsNullOrEmpty(CurrentPath)
|
||||||
|
? "Willkommen"
|
||||||
|
: "Dateien und Ordner" %>
|
||||||
|
</h2>
|
||||||
|
|
||||||
|
|
||||||
|
<p>
|
||||||
|
|
||||||
|
<%= string.IsNullOrEmpty(CurrentPath)
|
||||||
|
? "Es werden nur Bereiche angezeigt, auf die Ihr Benutzerkonto Zugriff hat."
|
||||||
|
: "Es werden nur zugängliche Ordner und Dateien angezeigt." %>
|
||||||
|
|
||||||
|
</p>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<%= ContentHtml %>
|
||||||
|
|
||||||
|
|
||||||
|
</main>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- ========================================================
|
||||||
|
FOOTER
|
||||||
|
======================================================== -->
|
||||||
|
|
||||||
|
<footer class="footer">
|
||||||
|
|
||||||
|
Interne Dokumentenablage
|
||||||
|
|
||||||
|
</footer>
|
||||||
|
|
||||||
|
|
||||||
|
</form>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
||||||
+1271
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,8 @@
|
|||||||
|
<%@ Page
|
||||||
|
Language="C#"
|
||||||
|
ResponseEncoding="utf-8"
|
||||||
|
ContentType="text/html; charset=utf-8"
|
||||||
|
AutoEventWireup="true"
|
||||||
|
CodeFile="Download.aspx.cs"
|
||||||
|
Inherits="FileSharePortal.Download"
|
||||||
|
%>
|
||||||
@@ -0,0 +1,342 @@
|
|||||||
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
using System.Security;
|
||||||
|
using System.Web;
|
||||||
|
using System.Web.UI;
|
||||||
|
|
||||||
|
namespace FileSharePortal
|
||||||
|
{
|
||||||
|
public partial class Download : Page
|
||||||
|
{
|
||||||
|
private const string ShareRoot =
|
||||||
|
@"\\LAN-DC1\Fileshare";
|
||||||
|
|
||||||
|
|
||||||
|
protected void Page_Load(
|
||||||
|
object sender,
|
||||||
|
EventArgs e)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Kein Caching.
|
||||||
|
*/
|
||||||
|
Response.Cache.SetCacheability(
|
||||||
|
HttpCacheability.NoCache);
|
||||||
|
|
||||||
|
Response.Cache.SetNoStore();
|
||||||
|
|
||||||
|
|
||||||
|
string relativePath =
|
||||||
|
Request.QueryString["path"];
|
||||||
|
|
||||||
|
|
||||||
|
if (string.IsNullOrWhiteSpace(relativePath))
|
||||||
|
{
|
||||||
|
Response.StatusCode = 400;
|
||||||
|
CompleteResponse();
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
string physicalPath;
|
||||||
|
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
physicalPath =
|
||||||
|
GetSafePhysicalFilePath(
|
||||||
|
relativePath);
|
||||||
|
}
|
||||||
|
catch (UnauthorizedAccessException)
|
||||||
|
{
|
||||||
|
Response.StatusCode = 403;
|
||||||
|
CompleteResponse();
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
catch (SecurityException)
|
||||||
|
{
|
||||||
|
Response.StatusCode = 403;
|
||||||
|
CompleteResponse();
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
catch (FileNotFoundException)
|
||||||
|
{
|
||||||
|
Response.StatusCode = 404;
|
||||||
|
CompleteResponse();
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
catch (DirectoryNotFoundException)
|
||||||
|
{
|
||||||
|
Response.StatusCode = 404;
|
||||||
|
CompleteResponse();
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
Response.StatusCode = 400;
|
||||||
|
CompleteResponse();
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Die Datei muss existieren.
|
||||||
|
*/
|
||||||
|
if (!File.Exists(physicalPath))
|
||||||
|
{
|
||||||
|
Response.StatusCode = 404;
|
||||||
|
CompleteResponse();
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ====================================================
|
||||||
|
* ZUGRIFF DES AKTUELL ANGEMELDETEN BENUTZERS PRÜFEN
|
||||||
|
* ====================================================
|
||||||
|
*
|
||||||
|
* Wegen
|
||||||
|
*
|
||||||
|
* <identity impersonate="true" />
|
||||||
|
*
|
||||||
|
* läuft dieser Zugriff unter dem angemeldeten
|
||||||
|
* AD-Benutzer.
|
||||||
|
*/
|
||||||
|
try
|
||||||
|
{
|
||||||
|
using (
|
||||||
|
FileStream stream =
|
||||||
|
new FileStream(
|
||||||
|
physicalPath,
|
||||||
|
FileMode.Open,
|
||||||
|
FileAccess.Read,
|
||||||
|
FileShare.ReadWrite |
|
||||||
|
FileShare.Delete))
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Datei erfolgreich geöffnet.
|
||||||
|
*
|
||||||
|
* Es wird hier absichtlich nichts gelesen.
|
||||||
|
* Das Öffnen reicht als Berechtigungsprüfung.
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (UnauthorizedAccessException)
|
||||||
|
{
|
||||||
|
Response.StatusCode = 403;
|
||||||
|
CompleteResponse();
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
catch (IOException)
|
||||||
|
{
|
||||||
|
Response.StatusCode = 403;
|
||||||
|
CompleteResponse();
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ====================================================
|
||||||
|
* DOWNLOAD AUSLIEFERN
|
||||||
|
* ====================================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
string fileName =
|
||||||
|
Path.GetFileName(
|
||||||
|
physicalPath);
|
||||||
|
|
||||||
|
|
||||||
|
string encodedFileName =
|
||||||
|
Uri.EscapeDataString(
|
||||||
|
fileName);
|
||||||
|
|
||||||
|
|
||||||
|
string contentType =
|
||||||
|
MimeMapping.GetMimeMapping(
|
||||||
|
physicalPath);
|
||||||
|
|
||||||
|
|
||||||
|
Response.Clear();
|
||||||
|
|
||||||
|
Response.Buffer = true;
|
||||||
|
|
||||||
|
Response.ContentType =
|
||||||
|
contentType;
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* UTF-8-Dateiname.
|
||||||
|
*
|
||||||
|
* Funktioniert auch für:
|
||||||
|
*
|
||||||
|
* Müller.pdf
|
||||||
|
* Änderungen.docx
|
||||||
|
* Köln.xlsx
|
||||||
|
* Rechnung März 2026.pdf
|
||||||
|
*/
|
||||||
|
Response.AddHeader(
|
||||||
|
"Content-Disposition",
|
||||||
|
"attachment; filename*=UTF-8''" +
|
||||||
|
encodedFileName
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Dateigröße setzen.
|
||||||
|
*/
|
||||||
|
FileInfo fileInfo =
|
||||||
|
new FileInfo(
|
||||||
|
physicalPath);
|
||||||
|
|
||||||
|
|
||||||
|
Response.AddHeader(
|
||||||
|
"Content-Length",
|
||||||
|
fileInfo.Length.ToString()
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Datei übertragen.
|
||||||
|
*/
|
||||||
|
Response.TransmitFile(
|
||||||
|
physicalPath);
|
||||||
|
|
||||||
|
|
||||||
|
CompleteResponse();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ========================================================
|
||||||
|
* SICHEREN DATEIPFAD ERMITTELN
|
||||||
|
* ========================================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
private string GetSafePhysicalFilePath(
|
||||||
|
string relativePath)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* URL-Decoding.
|
||||||
|
*/
|
||||||
|
string decoded =
|
||||||
|
HttpUtility.UrlDecode(
|
||||||
|
relativePath);
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* URL-Pfade in Windows-Pfade umwandeln.
|
||||||
|
*/
|
||||||
|
decoded =
|
||||||
|
decoded.Replace(
|
||||||
|
'/',
|
||||||
|
'\\');
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Keine absoluten Pfade erlauben.
|
||||||
|
*
|
||||||
|
* Verboten wären z.B.:
|
||||||
|
*
|
||||||
|
* \Windows\System32
|
||||||
|
* C:\...
|
||||||
|
* \\Server\Share
|
||||||
|
*/
|
||||||
|
if (
|
||||||
|
decoded.StartsWith("\\") ||
|
||||||
|
decoded.Contains(":"))
|
||||||
|
{
|
||||||
|
throw new SecurityException();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Path Traversal verhindern.
|
||||||
|
*/
|
||||||
|
string[] parts =
|
||||||
|
decoded.Split(
|
||||||
|
new[] { '\\' },
|
||||||
|
StringSplitOptions.RemoveEmptyEntries);
|
||||||
|
|
||||||
|
|
||||||
|
foreach (
|
||||||
|
string part
|
||||||
|
in parts)
|
||||||
|
{
|
||||||
|
if (
|
||||||
|
part == "." ||
|
||||||
|
part == "..")
|
||||||
|
{
|
||||||
|
throw new SecurityException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Vollständigen Dateipfad erzeugen.
|
||||||
|
*/
|
||||||
|
string fullPath =
|
||||||
|
Path.GetFullPath(
|
||||||
|
Path.Combine(
|
||||||
|
ShareRoot,
|
||||||
|
decoded));
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Root normalisieren.
|
||||||
|
*/
|
||||||
|
string normalizedRoot =
|
||||||
|
Path.GetFullPath(
|
||||||
|
ShareRoot)
|
||||||
|
.TrimEnd('\\') +
|
||||||
|
"\\";
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Der Pfad MUSS unterhalb von
|
||||||
|
* \\LAN-DC1\Fileshare bleiben.
|
||||||
|
*/
|
||||||
|
if (
|
||||||
|
!fullPath.StartsWith(
|
||||||
|
normalizedRoot,
|
||||||
|
StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
throw new SecurityException();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Datei muss existieren.
|
||||||
|
*/
|
||||||
|
if (!File.Exists(fullPath))
|
||||||
|
{
|
||||||
|
throw new FileNotFoundException();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return fullPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ========================================================
|
||||||
|
* RESPONSE BEENDEN
|
||||||
|
* ========================================================
|
||||||
|
*
|
||||||
|
* Kleine Hilfsmethode, damit Response.End()
|
||||||
|
* nicht unnötig in mehreren Stellen steht.
|
||||||
|
*/
|
||||||
|
private void CompleteResponse()
|
||||||
|
{
|
||||||
|
HttpContext.Current.ApplicationInstance
|
||||||
|
.CompleteRequest();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in new issue
Block a user