initial commit file manager project
This commit is contained in:
commit
d276d45b7a
39
Frontend/index.html
Normal file
39
Frontend/index.html
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>Filemanager</title>
|
||||||
|
|
||||||
|
<script src="static/js/views.js"></script>
|
||||||
|
<script src="static/js/tools.js"></script>
|
||||||
|
<script src="static/js/index.js"></script>
|
||||||
|
|
||||||
|
<link href="https://fonts.googleapis.com/css?family=Material+Icons" rel="stylesheet">
|
||||||
|
<link href="https://fonts.googleapis.com/css?family=Ubuntu" rel="stylesheet">
|
||||||
|
|
||||||
|
<link href="static/css/components.css" rel="stylesheet">
|
||||||
|
<link href="static/css/login.css" rel="stylesheet">
|
||||||
|
|
||||||
|
<link href="static/css/index.css" rel="stylesheet">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<header>
|
||||||
|
<div class="app-header">
|
||||||
|
<div class="title">Filemanager</div>
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
<main>
|
||||||
|
<div class="box">
|
||||||
|
<div id="wrapper">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
<footer>
|
||||||
|
<div class="box">
|
||||||
|
<a href="impressum.html">Impressum</a>
|
||||||
|
</div>
|
||||||
|
</footer>
|
||||||
|
</body>
|
||||||
|
</html>
|
72
Frontend/static/css/components.css
Normal file
72
Frontend/static/css/components.css
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
html, body {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
height: 100%;
|
||||||
|
min-height: 100%;
|
||||||
|
overflow: hidden;
|
||||||
|
background: #212121;
|
||||||
|
font-family: "Ubuntu", sans-serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
main {
|
||||||
|
flex: 1 1 auto;
|
||||||
|
overflow-y: scroll;
|
||||||
|
}
|
||||||
|
|
||||||
|
footer {
|
||||||
|
/*flex: 0 0 auto;*/
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
header {
|
||||||
|
flex: 0 0 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.app-header {
|
||||||
|
box-shadow: 1px 1px 10px rgb(33, 33, 33);
|
||||||
|
overflow: hidden;
|
||||||
|
-webkit-user-select: none;
|
||||||
|
background-color: #404040;
|
||||||
|
color: #ffffff;
|
||||||
|
display: grid;
|
||||||
|
grid-gap: 5%;
|
||||||
|
grid-template-columns: 25% 40% 25%;
|
||||||
|
height: auto;
|
||||||
|
max-height: 100px;
|
||||||
|
padding: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title {
|
||||||
|
margin: 5px;
|
||||||
|
font-size: 2em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.box {
|
||||||
|
padding: 5px;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
button {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.material-icon {
|
||||||
|
font-family: Material Icons, sans-serif !important;
|
||||||
|
font-weight: 400;
|
||||||
|
font-style: normal;
|
||||||
|
font-size: 24px;
|
||||||
|
line-height: 1;
|
||||||
|
letter-spacing: normal;
|
||||||
|
text-transform: none;
|
||||||
|
display: inline-block;
|
||||||
|
white-space: nowrap;
|
||||||
|
word-wrap: normal;
|
||||||
|
direction: ltr;
|
||||||
|
-webkit-font-feature-settings: "liga";
|
||||||
|
-webkit-font-smoothing: antialiased;
|
||||||
|
}
|
88
Frontend/static/css/index.css
Normal file
88
Frontend/static/css/index.css
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
#wrapper {
|
||||||
|
color: white;
|
||||||
|
padding: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#wrapper1 {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 30% 70%;
|
||||||
|
}
|
||||||
|
|
||||||
|
#tree {
|
||||||
|
grid-column: 1;
|
||||||
|
margin: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#path {
|
||||||
|
padding-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.arrow-pointer {
|
||||||
|
display: inline-block;
|
||||||
|
height: 2em;
|
||||||
|
background: #404040;
|
||||||
|
position: relative;
|
||||||
|
color: #ffffff;
|
||||||
|
margin-left: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.arrow-pointer:first-child {
|
||||||
|
margin-left: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.arrow-pointer span {
|
||||||
|
padding-left: 1.5em;
|
||||||
|
padding-right: 0.5em;
|
||||||
|
padding-top: 0.5em;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.arrow-pointer:after {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
bottom: 0;
|
||||||
|
width: 0;
|
||||||
|
height: 0;
|
||||||
|
border-left: 1em solid #212121;
|
||||||
|
border-top: 1em solid #404040;
|
||||||
|
border-bottom: 1em solid #404040;
|
||||||
|
}
|
||||||
|
|
||||||
|
.arrow-pointer:before {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
right: -1em;
|
||||||
|
bottom: 0;
|
||||||
|
width: 0;
|
||||||
|
height: 0;
|
||||||
|
border-left: 1em solid #404040;
|
||||||
|
border-top: 1em solid #212121;
|
||||||
|
border-bottom: 1em solid #212121;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#files {
|
||||||
|
grid-column: 2;
|
||||||
|
margin: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
table {
|
||||||
|
width: 100%;
|
||||||
|
border-collapse: collapse;
|
||||||
|
}
|
||||||
|
|
||||||
|
tr {
|
||||||
|
height: 3em;
|
||||||
|
}
|
||||||
|
|
||||||
|
th, td {
|
||||||
|
border-bottom: 1px solid #ccc;
|
||||||
|
}
|
||||||
|
|
||||||
|
thead tr {
|
||||||
|
text-align: left;
|
||||||
|
background: #0062ff;
|
||||||
|
}
|
38
Frontend/static/css/login.css
Normal file
38
Frontend/static/css/login.css
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
#wrapper {
|
||||||
|
height: 100%;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
#login {
|
||||||
|
margin-right: auto;
|
||||||
|
margin-left: auto;
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
#login h1 {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
#login input, #login button {
|
||||||
|
font-size: 2em;
|
||||||
|
-webkit-appearance: none;
|
||||||
|
box-sizing: border-box;
|
||||||
|
height: 2.5em;
|
||||||
|
width: 100%;
|
||||||
|
border: none;
|
||||||
|
border-radius: 5px;
|
||||||
|
padding: 10px;
|
||||||
|
margin: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#login input {
|
||||||
|
background-color: #404040;
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
#login button {
|
||||||
|
background-color: #003100;
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
104
Frontend/static/js/index.js
Normal file
104
Frontend/static/js/index.js
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
tree = [];
|
||||||
|
|
||||||
|
window.addEventListener('load', function () {
|
||||||
|
console.log('All assets are loaded');
|
||||||
|
|
||||||
|
if (sessionStorage.getItem("authorization") !== null) {
|
||||||
|
console.log('Logged in');
|
||||||
|
url_listener();
|
||||||
|
} else {
|
||||||
|
console.log('Not logged in');
|
||||||
|
create_login_view();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
window.addEventListener('popstate', function () {
|
||||||
|
url_listener();
|
||||||
|
});
|
||||||
|
|
||||||
|
function url_listener() {
|
||||||
|
let curr_dir = findGetParameter('path');
|
||||||
|
|
||||||
|
if (curr_dir !== null) {
|
||||||
|
httpGetAsync('http://localhost:8080' + curr_dir, null, show_files);
|
||||||
|
} else {
|
||||||
|
httpGetAsync('http://localhost:8080', null, show_files);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function login() {
|
||||||
|
let username = document.getElementById("username").value;
|
||||||
|
let password = document.getElementById("password").value;
|
||||||
|
|
||||||
|
const xmlHttp = new XMLHttpRequest();
|
||||||
|
xmlHttp.onreadystatechange = function () {
|
||||||
|
if (this.readyState === 4) {
|
||||||
|
if (xmlHttp.status === 200) {
|
||||||
|
console.log(username + ':' + JSON.parse(xmlHttp.responseText)['token'])
|
||||||
|
sessionStorage.setItem("authorization", btoa(username + ':' + JSON.parse(xmlHttp.responseText)['token']));
|
||||||
|
|
||||||
|
httpGetAsync('http://localhost:8080', null, show_files);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
xmlHttp.open("POST", 'http://localhost:8080/login', true);
|
||||||
|
xmlHttp.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
|
||||||
|
xmlHttp.send('username=' + username + '&password=' + password);
|
||||||
|
}
|
||||||
|
|
||||||
|
function show_files(response, code) {
|
||||||
|
document.getElementById("wrapper").innerHTML = '';
|
||||||
|
if (code === 200) {
|
||||||
|
// OK
|
||||||
|
console.log(code);
|
||||||
|
console.log(JSON.parse(response));
|
||||||
|
create_file_view(JSON.parse(response));
|
||||||
|
} else if (code === 401) {
|
||||||
|
// Not logged in
|
||||||
|
sessionStorage.removeItem('authorization');
|
||||||
|
// location.reload();
|
||||||
|
} else {
|
||||||
|
// Error
|
||||||
|
console.error(code);
|
||||||
|
console.error(JSON.parse(response));
|
||||||
|
sessionStorage.removeItem('authorization');
|
||||||
|
// location.reload();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function one_dir_back() {
|
||||||
|
let curr_dir = findGetParameter('path');
|
||||||
|
|
||||||
|
let dir = curr_dir.split('/');
|
||||||
|
dir = dir.slice(0, dir.length - 1);
|
||||||
|
curr_dir = dir.join('/');
|
||||||
|
|
||||||
|
return curr_dir;
|
||||||
|
}
|
||||||
|
|
||||||
|
// function change_dir(name) {
|
||||||
|
// let curr_dir = findGetParameter('path');
|
||||||
|
//
|
||||||
|
// if(curr_dir === null) {
|
||||||
|
// curr_dir = '';
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// if (name === '..') {
|
||||||
|
// let dir = curr_dir.split('/');
|
||||||
|
// dir = dir.slice(0, dir.length - 1);
|
||||||
|
// curr_dir = dir.join('/');
|
||||||
|
//
|
||||||
|
// httpGetAsync('http://localhost:8080' + curr_dir, null, show_files);
|
||||||
|
// window.history.pushState('index', 'Filemanager', 'index.html?path=' + curr_dir);
|
||||||
|
// } else {
|
||||||
|
// httpGetAsync('http://localhost:8080' + curr_dir + '/' + name, null, show_files);
|
||||||
|
// window.history.pushState('index', 'Filemanager', 'index.html?path=' + curr_dir + '/' + name);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
function load_file(name) {
|
||||||
|
let curr_dir = findGetParameter('path');
|
||||||
|
|
||||||
|
console.log(curr_dir + '/' + name);
|
||||||
|
}
|
67
Frontend/static/js/tools.js
Normal file
67
Frontend/static/js/tools.js
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
function httpGetAsync(url, data, callback) { // data includes auth
|
||||||
|
const xmlHttp = new XMLHttpRequest();
|
||||||
|
xmlHttp.onreadystatechange = function () {
|
||||||
|
if (this.readyState === 4) {
|
||||||
|
callback(xmlHttp.responseText, xmlHttp.status);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(url)
|
||||||
|
xmlHttp.open("GET", url, true);
|
||||||
|
xmlHttp.setRequestHeader('Authorization', 'Basic ' + sessionStorage.getItem('authorization'));
|
||||||
|
xmlHttp.send(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
function httpPostAsync(url, data, callback) {
|
||||||
|
const xmlHttp = new XMLHttpRequest();
|
||||||
|
xmlHttp.onreadystatechange = function () {
|
||||||
|
if (this.readyState === 4) {
|
||||||
|
callback(xmlHttp.responseText, xmlHttp.status);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
xmlHttp.open("POST", url, true);
|
||||||
|
xmlHttp.setRequestHeader('Authorization', 'Basic ' + sessionStorage.getItem('authorization'));
|
||||||
|
xmlHttp.setRequestHeader('Content-Type', 'application/json');
|
||||||
|
xmlHttp.send(JSON.stringify(data));
|
||||||
|
}
|
||||||
|
|
||||||
|
function httpDeleteAsync(url, data, callback) {
|
||||||
|
const xmlHttp = new XMLHttpRequest();
|
||||||
|
xmlHttp.onreadystatechange = function () {
|
||||||
|
if (this.readyState === 4) {
|
||||||
|
callback(xmlHttp.responseText, xmlHttp.status);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
xmlHttp.open("DELETE", url, true);
|
||||||
|
xmlHttp.setRequestHeader('Authorization', 'Basic ' + sessionStorage.getItem('authorization'));
|
||||||
|
xmlHttp.send();
|
||||||
|
}
|
||||||
|
|
||||||
|
function httpPutAsync(url, data, callback) {
|
||||||
|
const xmlHttp = new XMLHttpRequest();
|
||||||
|
xmlHttp.onreadystatechange = function () {
|
||||||
|
if (this.readyState === 4) {
|
||||||
|
callback(xmlHttp.responseText, xmlHttp.status);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
xmlHttp.open("PUT", url, true);
|
||||||
|
xmlHttp.setRequestHeader('Authorization', 'Basic ' + sessionStorage.getItem('authorization'));
|
||||||
|
xmlHttp.setRequestHeader('Content-Type', 'application/json');
|
||||||
|
xmlHttp.send(JSON.stringify(data));
|
||||||
|
}
|
||||||
|
|
||||||
|
function findGetParameter(parameterName) {
|
||||||
|
let result = null,
|
||||||
|
tmp = [];
|
||||||
|
location.search
|
||||||
|
.substr(1)
|
||||||
|
.split("&")
|
||||||
|
.forEach(function (item) {
|
||||||
|
tmp = item.split("=");
|
||||||
|
if (tmp[0] === parameterName) result = decodeURIComponent(tmp[1]);
|
||||||
|
});
|
||||||
|
return result;
|
||||||
|
}
|
116
Frontend/static/js/views.js
Normal file
116
Frontend/static/js/views.js
Normal file
@ -0,0 +1,116 @@
|
|||||||
|
function create_login_view() {
|
||||||
|
let tmp = document.createElement('div');
|
||||||
|
tmp.innerHTML = `<div id="login">
|
||||||
|
<form>
|
||||||
|
<h1>Login</h1>
|
||||||
|
<div>
|
||||||
|
<label for="username"></label>
|
||||||
|
<input type="text" name="username" id="username" placeholder="Username" value="admin">
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<label for="password"></label>
|
||||||
|
<input type="password" name="password" id="password" placeholder="Password" value="admin">
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<button type="button" value="Login" onclick="login();">Login</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>`;
|
||||||
|
document.getElementById("wrapper").appendChild(tmp.firstChild);
|
||||||
|
}
|
||||||
|
|
||||||
|
// function create_tree_view(data) {
|
||||||
|
// let curr_dir = findGetParameter('path');
|
||||||
|
// let path = curr_dir.split('/');
|
||||||
|
//
|
||||||
|
// for (let i = 0; i < data.length; i++) {
|
||||||
|
// if (tree[path[0]] === null) {
|
||||||
|
// tree[path[0]] = {};
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// if (data[i]['Type'] === 'dir') {
|
||||||
|
//
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// console.log(data)
|
||||||
|
// }
|
||||||
|
|
||||||
|
function create_file_view(data) {
|
||||||
|
let curr_dir = findGetParameter('path');
|
||||||
|
|
||||||
|
let tmp = document.createElement('div');
|
||||||
|
tmp.innerHTML = `<div id="wrapper1">
|
||||||
|
<div id="tree">Div 1</div>
|
||||||
|
<div id="files">
|
||||||
|
<div id="path"></div>
|
||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Icon</th>
|
||||||
|
<th>Name</th>
|
||||||
|
<th>Größe</th>
|
||||||
|
<th>Datum</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr id="back" style="cursor: pointer" onclick="window.history.pushState('index', 'Filemanager', 'index.html?path=' + one_dir_back()); url_listener()">
|
||||||
|
<td data-order="___"></td>
|
||||||
|
<td>..</td>
|
||||||
|
<td></td>
|
||||||
|
<td></td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>`;
|
||||||
|
|
||||||
|
// Folders
|
||||||
|
for (let i = 0; i < data.length; i++) {
|
||||||
|
if (data[i]['Type'] === 'dir') {
|
||||||
|
let tmp1 = document.createElement('tr');
|
||||||
|
tmp1.style = 'cursor: pointer;';
|
||||||
|
tmp1.onclick = function () {
|
||||||
|
if (curr_dir === null) curr_dir = '';
|
||||||
|
window.history.pushState('index', 'Filemanager', 'index.html?path=' + curr_dir + '/' + data[i]['Name']);
|
||||||
|
url_listener();
|
||||||
|
};
|
||||||
|
tmp1.innerHTML = `<td data-order="__"><span class="material-icon">folder</span></td>
|
||||||
|
<td>${data[i]['Name']}</td>
|
||||||
|
<td>--</td>
|
||||||
|
<td>--</td>`;
|
||||||
|
tmp.getElementsByTagName('tbody')[0].appendChild(tmp1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Files
|
||||||
|
for (let i = 0; i < data.length; i++) {
|
||||||
|
if (data[i]['Type'] !== 'dir') {
|
||||||
|
let tmp1 = document.createElement('tr');
|
||||||
|
tmp1.style = 'cursor: pointer;';
|
||||||
|
tmp1.onclick = function () {
|
||||||
|
if (curr_dir === null) curr_dir = '';
|
||||||
|
load_file(curr_dir, data[i]['Name']);
|
||||||
|
};
|
||||||
|
tmp1.innerHTML = `<td data-order="__"><span class="material-icon">description</span></td>
|
||||||
|
<td>${data[i]['Name']}</td>
|
||||||
|
<td>--</td>
|
||||||
|
<td>--</td>`;
|
||||||
|
tmp.getElementsByTagName('tbody')[0].appendChild(tmp1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Path
|
||||||
|
let tmp1 = document.createElement('div');
|
||||||
|
let s = `<div onclick="window.history.pushState('index', 'Filemanager', 'index.html?path='); url_listener()" class="arrow-pointer" style="cursor: pointer;z-index: 1000"><span>/</span></div>`;
|
||||||
|
|
||||||
|
if (curr_dir !== null) {
|
||||||
|
let folders = curr_dir.split('/');
|
||||||
|
for (let i = 1; i < folders.length; i++) {
|
||||||
|
s = s.concat(`<div onclick="window.history.pushState('index', 'Filemanager', 'index.html?path=${folders.slice(0, i + 1).join('/')}'); url_listener()" class="arrow-pointer" style="cursor: pointer;z-index: ${folders.length - i}"><span>${folders[i]}</span></div>`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
tmp1.innerHTML = s;
|
||||||
|
tmp.getElementsByTagName('div')[3].appendChild(tmp1);
|
||||||
|
|
||||||
|
document.getElementById("wrapper").appendChild(tmp.firstChild);
|
||||||
|
}
|
BIN
WebService/data/images/Flugzeug.png
Normal file
BIN
WebService/data/images/Flugzeug.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 105 KiB |
BIN
WebService/data/music/horse.mp3
Normal file
BIN
WebService/data/music/horse.mp3
Normal file
Binary file not shown.
7
WebService/data/texts/Letter_to_grandma.txt
Normal file
7
WebService/data/texts/Letter_to_grandma.txt
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
Hi Granny,
|
||||||
|
|
||||||
|
how are you? Hope you are doing good!
|
||||||
|
I really miss your cake. Hope to see you soon.
|
||||||
|
|
||||||
|
Best,
|
||||||
|
Larry
|
1
WebService/data/texts/Schoolpapers/C_Programming.txt
Normal file
1
WebService/data/texts/Schoolpapers/C_Programming.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
it all started with "Hello World!"
|
1
WebService/data/texts/Schoolpapers/WebEngineering.txt
Normal file
1
WebService/data/texts/Schoolpapers/WebEngineering.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
Its just amazing!
|
1
WebService/data/texts/Text_for_Moonlanding.txt
Normal file
1
WebService/data/texts/Text_for_Moonlanding.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
That's one small step for (a) man, one giant leap for mankind.
|
BIN
WebService/data/videos/rocket.mp4
Normal file
BIN
WebService/data/videos/rocket.mp4
Normal file
Binary file not shown.
186
WebService/index.php
Normal file
186
WebService/index.php
Normal file
@ -0,0 +1,186 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
Spec:
|
||||||
|
|
||||||
|
|
||||||
|
/login ... => login user
|
||||||
|
/logout .. => logout user
|
||||||
|
|
||||||
|
/... => URL to files and folders:
|
||||||
|
|
||||||
|
GET /<DIR>
|
||||||
|
= return file/folders in this dir
|
||||||
|
|
||||||
|
POST /<DIR>
|
||||||
|
= create the directory and send message back
|
||||||
|
|
||||||
|
DELETE <DIR>
|
||||||
|
= delete the directory
|
||||||
|
|
||||||
|
GET /<file>
|
||||||
|
= return binary data of file
|
||||||
|
|
||||||
|
POST /<file>
|
||||||
|
= create the file with corresponding content
|
||||||
|
|
||||||
|
DELETE /<file>
|
||||||
|
= delete the file and send message
|
||||||
|
|
||||||
|
|
||||||
|
Authentication workflow:
|
||||||
|
|
||||||
|
POST /login with username password => return token
|
||||||
|
|
||||||
|
All other requests:
|
||||||
|
authorization: Basic base64(username.token)
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
require "lib/Folder.php";
|
||||||
|
require "lib/File.php";
|
||||||
|
require "lib/Authenticator.php";
|
||||||
|
|
||||||
|
$authorized = false;
|
||||||
|
|
||||||
|
//first check if user is valid
|
||||||
|
$headers = getallheaders();
|
||||||
|
$auth = array(2);
|
||||||
|
if(isset($headers["Authorization"])){
|
||||||
|
$temp = explode(" ",$headers["Authorization"]);
|
||||||
|
$raw_auth = base64_decode($temp[1]);
|
||||||
|
$auth = explode(":",$raw_auth);
|
||||||
|
$authenticator = new Authenticator();
|
||||||
|
$authorized = $authenticator->verifyToken($auth[0],$auth[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
$url = filter_input(INPUT_SERVER,"REQUEST_URI",FILTER_SANITIZE_URL);
|
||||||
|
|
||||||
|
$paramPos = strpos($url,"?");
|
||||||
|
if($paramPos == 0){
|
||||||
|
$path = $url;
|
||||||
|
} else {
|
||||||
|
$path = substr($url,0,$paramPos);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
$method = filter_input(INPUT_SERVER,"REQUEST_METHOD",FILTER_SANITIZE_FULL_SPECIAL_CHARS);
|
||||||
|
if($path != "/login" && !$authorized){
|
||||||
|
http_response_code(401);
|
||||||
|
echo '{"error": "authorization failed"}';
|
||||||
|
} else if($path == "/login"){
|
||||||
|
$username = filter_input(INPUT_POST,"username",FILTER_SANITIZE_FULL_SPECIAL_CHARS);
|
||||||
|
$password = filter_input(INPUT_POST,"password",FILTER_SANITIZE_FULL_SPECIAL_CHARS);
|
||||||
|
$authenticator = new Authenticator();
|
||||||
|
$result = $authenticator->authUser($username, $password);
|
||||||
|
if(!$result){
|
||||||
|
http_response_code(401);
|
||||||
|
echo '{"error": "authentication failed"}';
|
||||||
|
} else {
|
||||||
|
http_response_code(200);
|
||||||
|
echo '{"token": "'.$result.'"}';
|
||||||
|
}
|
||||||
|
} else if($path == "/logout"){
|
||||||
|
if(count($auth) > 0){
|
||||||
|
$authenticator = new Authenticator();
|
||||||
|
if(!$authenticator->logoutToken($auth[0], $auth[1])){
|
||||||
|
http_response_code(500);
|
||||||
|
echo '{"error": "logout failed"}';
|
||||||
|
} else {
|
||||||
|
http_response_code(200);
|
||||||
|
echo '{"message": "logout successful"}';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if($authorized){
|
||||||
|
$fullPath = __DIR__."/data".urldecode($path);
|
||||||
|
|
||||||
|
if($method == "GET"){
|
||||||
|
$isDir = Folder::isDirectory($fullPath);
|
||||||
|
if($isDir){
|
||||||
|
$dir = new Folder($fullPath);
|
||||||
|
$entries = $dir->getEntries();
|
||||||
|
if($entries === false){
|
||||||
|
http_response_code(500);
|
||||||
|
echo '{"error": "failed to load directory entries"}';
|
||||||
|
} else {
|
||||||
|
http_response_code(200);
|
||||||
|
echo json_encode($entries);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$file = new File($fullPath);
|
||||||
|
if($file->doExists()){
|
||||||
|
if(isset($_GET["format"]) && filter_input(INPUT_GET,"format",FILTER_SANITIZE_FULL_SPECIAL_CHARS) == "base64"){
|
||||||
|
echo base64_encode($file->getContent());
|
||||||
|
} else {
|
||||||
|
header('Content-Type: '.$file->getMimeType());
|
||||||
|
header('Content-Disposition: attachment; filename="'.$file->getFilename().'"');
|
||||||
|
echo $file->getContent();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
http_response_code(500);
|
||||||
|
echo '{"error": "file does not exist"}';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if($method == "POST"){
|
||||||
|
if(isset($_POST["type"]) && filter_input(INPUT_POST,"type",FILTER_SANITIZE_FULL_SPECIAL_CHARS) == "dir"){
|
||||||
|
$isDir = true;
|
||||||
|
} else {
|
||||||
|
$isDir = false;
|
||||||
|
}
|
||||||
|
if($isDir){
|
||||||
|
$dir = new Folder($fullPath);
|
||||||
|
if($dir->create() === false){
|
||||||
|
http_response_code(500);
|
||||||
|
echo '{"error": "failed to create directory"}';
|
||||||
|
} else {
|
||||||
|
http_response_code(200);
|
||||||
|
echo '{"message": "directory created successfully"}';
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if(count($_FILES) == 0){ //no upload
|
||||||
|
$file = new File($fullPath);
|
||||||
|
//no filter, since we need to write the file as is
|
||||||
|
$result = $file->writeContent(base64_decode($_POST["content"]));
|
||||||
|
} else {
|
||||||
|
$file = new File($fullPath);
|
||||||
|
$result = $file->createFromUpload($_FILES["newFile"]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if($result === false){
|
||||||
|
http_response_code(500);
|
||||||
|
echo '{"error": "faild to write file"}';
|
||||||
|
} else {
|
||||||
|
http_response_code(200);
|
||||||
|
echo '{"message": "file written successfully"}';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if($method == "DELETE"){
|
||||||
|
$isDir = Folder::isDirectory($fullPath);
|
||||||
|
if($isDir){
|
||||||
|
$dir = new Folder($fullPath);
|
||||||
|
if(!$dir->delete()){
|
||||||
|
http_response_code(500);
|
||||||
|
echo '{"error": "failed to delete directory"}';
|
||||||
|
} else {
|
||||||
|
http_response_code(200);
|
||||||
|
echo '{"message": "directory deleted successfully"}';
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$file = new File($fullPath);
|
||||||
|
if(!$file->delete()){
|
||||||
|
http_response_code(500);
|
||||||
|
echo '{"error": "failed to delete file"}';
|
||||||
|
} else {
|
||||||
|
http_response_code(200);
|
||||||
|
echo '{"message": "file deleted successfully"}';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
118
WebService/lib/Authenticator.php
Normal file
118
WebService/lib/Authenticator.php
Normal file
@ -0,0 +1,118 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
class Authenticator{
|
||||||
|
|
||||||
|
private $dbDN = "sqlite:auth.db";
|
||||||
|
private $tokenValidity = 600;
|
||||||
|
|
||||||
|
private function createInitalDB(){
|
||||||
|
$db = new PDO($this->dbDN);
|
||||||
|
$db->exec("CREATE TABLE users (user TEXT, pass TEXT)");
|
||||||
|
$db->exec("INSERT INTO users VALUES('admin','".md5("admin")."')");
|
||||||
|
$db->exec("CREATE TABLE tokens (username TEXT, token TEXT, validTo INT)");
|
||||||
|
unset($db);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function createToken($username){
|
||||||
|
|
||||||
|
$token = md5($username.time());
|
||||||
|
$validTo = time()+$this->tokenValidity;
|
||||||
|
|
||||||
|
$db = new PDO($this->dbDN);
|
||||||
|
$stmt = $db->prepare("INSERT INTO tokens VALUES (:USER, :TOKEN, :VALIDTO)");
|
||||||
|
$result = $stmt->execute(array(
|
||||||
|
":USER" => $username,
|
||||||
|
":TOKEN" => $token,
|
||||||
|
":VALIDTO" => $validTo
|
||||||
|
));
|
||||||
|
unset($db);
|
||||||
|
if($result){
|
||||||
|
return $token;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function createUser($username,$password){
|
||||||
|
$db = new PDO($this->dbDN);
|
||||||
|
$stmt = $db->prepare("INSERT INTO users VALUES(:USER,:PASS)");
|
||||||
|
$result = $stmt->execute(array(
|
||||||
|
":USER" => $username,
|
||||||
|
":PASS" => md5($password)
|
||||||
|
));
|
||||||
|
unset($db);
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function deleteUser($username){
|
||||||
|
$db = new PDO($this->dbDN);
|
||||||
|
$stmt = $db->prepare("DELETE FROM users WHERE user = :USER");
|
||||||
|
$result = $stmt->execute(array(
|
||||||
|
":USER" => $username
|
||||||
|
));
|
||||||
|
unset($db);
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function authUser($username,$password){
|
||||||
|
if(!file_exists("auth.db")){
|
||||||
|
$this->createInitalDB();
|
||||||
|
}
|
||||||
|
$db = new PDO($this->dbDN);
|
||||||
|
$stmt = $db->prepare("SELECT COUNT(*) AS NUMUSER FROM users WHERE user = :USER and pass = :PASS");
|
||||||
|
$result = $stmt->execute(array(
|
||||||
|
":USER" => $username,
|
||||||
|
":PASS" => md5($password)
|
||||||
|
));
|
||||||
|
if($result){
|
||||||
|
$temp = $stmt->fetchAll();
|
||||||
|
if(intval($temp[0]["NUMUSER"]) == 1){
|
||||||
|
return $this->createToken($username);
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public function verifyToken($username,$token){
|
||||||
|
$db = new PDO($this->dbDN);
|
||||||
|
$stmt = $db->prepare("SELECT COUNT(*) AS NUMTOK FROM tokens WHERE username = :USER and token = :TOKEN and validTo >= :VALIDTO");
|
||||||
|
$result = $stmt->execute(array(
|
||||||
|
":USER" => $username,
|
||||||
|
":TOKEN" => $token,
|
||||||
|
":VALIDTO" => time()
|
||||||
|
));
|
||||||
|
if($result){
|
||||||
|
$temp = $stmt->fetchAll();
|
||||||
|
if(intval($temp[0]["NUMTOK"]) == 1){
|
||||||
|
$stmt2 = $db->prepare("UPDATE tokens SET validTo = :VALIDTO WHERE token = :TOKEN");
|
||||||
|
$result = $stmt2->execute(array(
|
||||||
|
":VALIDTO" => time()+$this->tokenValidity,
|
||||||
|
":TOKEN" => $token
|
||||||
|
));
|
||||||
|
unset($db);
|
||||||
|
return $result;
|
||||||
|
} else {
|
||||||
|
unset($db);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
unset($db);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public function logoutToken($username, $token){
|
||||||
|
$db = new PDO($this->dbDN);
|
||||||
|
$stmt = $db->prepare("DELETE FROM tokens WHERE username = :USER AND token = :TOKEN");
|
||||||
|
$result = $stmt->execute(array(
|
||||||
|
":USER" => $username,
|
||||||
|
":TOKEN" => $token
|
||||||
|
));
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
}
|
49
WebService/lib/File.php
Normal file
49
WebService/lib/File.php
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
class File {
|
||||||
|
private $fullFilename = "";
|
||||||
|
|
||||||
|
public function __construct($fullFilename){
|
||||||
|
$this->fullFilename = $fullFilename;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function doExists(){
|
||||||
|
return file_exists($this->fullFilename);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getMimeType(){
|
||||||
|
return mime_content_type($this->fullFilename);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getContent(){
|
||||||
|
return file_get_contents($this->fullFilename);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function delete(){
|
||||||
|
return unlink($this->fullFilename);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getFilePath(){
|
||||||
|
return dirname($this->fullFilename);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getFilename(){
|
||||||
|
return basename($this->fullFilename);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function writeToFile($data,$flag){
|
||||||
|
return file_put_contents($this->fullFilename,$data,$flag);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function addContent($data){
|
||||||
|
return $this->writeToFile($data,FILE_APPEND);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function writeContent($data){
|
||||||
|
return $this->writeToFile($data,0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function createFromUpload($file){
|
||||||
|
move_uploaded_file($file['tmp_name'],$this->fullFilename);
|
||||||
|
}
|
||||||
|
}
|
63
WebService/lib/Folder.php
Normal file
63
WebService/lib/Folder.php
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
class Folder{
|
||||||
|
private $fullDirname = "";
|
||||||
|
|
||||||
|
public static function isDirectory($fullPath){
|
||||||
|
return is_dir($fullPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function __construct($fullDirname){
|
||||||
|
if(substr($fullDirname,-1,1)=="/" && $fullDirname != "/"){
|
||||||
|
$fullDirname=substr($fullDirname,0,-1);
|
||||||
|
}
|
||||||
|
$this->fullDirname = $fullDirname;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function create(){
|
||||||
|
return mkdir($this->fullDirname);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function isEmpty(){
|
||||||
|
return (count(scandir($this->fullDirname)) <= 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function delete(){
|
||||||
|
if($this->isEmpty()){
|
||||||
|
return rmdir($this->fullDirname);
|
||||||
|
}else{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getFoldername(){
|
||||||
|
return basename($this->fullDirname);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getFolderpath(){
|
||||||
|
return dirname($this->fullDirname);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getEntries(){
|
||||||
|
$entries = array();
|
||||||
|
if($dir = opendir($this->fullDirname)){
|
||||||
|
|
||||||
|
while (false !== ($entry = readdir($dir))) {
|
||||||
|
if($entry != "." && $entry != ".."){
|
||||||
|
if(is_dir($this->fullDirname."/".$entry)){
|
||||||
|
$temp = array("Name" => $entry, "Type" => "dir");
|
||||||
|
}else{
|
||||||
|
$temp = array("Name" => $entry, "Type" => mime_content_type($this->fullDirname."/".$entry));
|
||||||
|
}
|
||||||
|
array_push($entries,$temp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
closedir($dir);
|
||||||
|
return $entries;
|
||||||
|
|
||||||
|
}else{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
12
WebService/router.php
Normal file
12
WebService/router.php
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
<?php
|
||||||
|
header("Access-Control-Allow-Origin: *");
|
||||||
|
if($_SERVER["REQUEST_METHOD"] == "OPTIONS"){
|
||||||
|
http_response_code(200);
|
||||||
|
header("Access-Control-Allow-Methods: POST, GET, OPTIONS, DELETE");
|
||||||
|
header("Access-Control-Allow-Headers: authorization, origin, content-type, accept, x-requested-with");
|
||||||
|
header("Access-Control-Max-Age: 3600");
|
||||||
|
} else {
|
||||||
|
include "index.php";
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
|
4
WebService/upload.ini
Normal file
4
WebService/upload.ini
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
file_uploads = On
|
||||||
|
memory_limit = 64M
|
||||||
|
upload_max_filesize = 64M
|
||||||
|
post_max_size = 64M
|
Loading…
Reference in New Issue
Block a user