mirror of
https://github.com/C5H12O5/syno-videoinfo-plugin.git
synced 2026-01-14 00:49:31 +00:00
Add basic authorization support
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@ -382,3 +382,4 @@ cython_debug/
|
||||
INFO
|
||||
.cache_*
|
||||
scrapeflows.conf
|
||||
configserver/authorization
|
||||
@ -32,7 +32,7 @@ def render_index(saved=None):
|
||||
"movie": "selected" if "movie" in types else "disabled",
|
||||
"tvshow": "selected" if "tvshow" in types else "disabled",
|
||||
"priority": len(sites),
|
||||
"config": config_html
|
||||
"config": config_html,
|
||||
}
|
||||
if saved_conf is not None:
|
||||
saved_types = saved_conf["types"]
|
||||
@ -101,33 +101,66 @@ _index_html = render_index()
|
||||
class RequestHandler(http.server.SimpleHTTPRequestHandler):
|
||||
"""Request handler for the HTTP server."""
|
||||
|
||||
def do_AUTH(self):
|
||||
filepath = _basedir / "authorization"
|
||||
if not filepath.exists():
|
||||
return True
|
||||
|
||||
with open(filepath, "r", encoding="utf-8") as reader:
|
||||
saved_auth = reader.read()
|
||||
|
||||
if self.headers.get("Authorization") is not None:
|
||||
auth_header = self.headers.get("Authorization")
|
||||
if auth_header.split("Basic ")[1] == saved_auth:
|
||||
return True
|
||||
|
||||
self.send_response(401)
|
||||
self.send_header("WWW-Authenticate", 'Basic realm="Login Required"')
|
||||
self.send_header("Content-type", "text/html")
|
||||
self.end_headers()
|
||||
self.wfile.write(b"Unauthorized")
|
||||
return False
|
||||
|
||||
def do_GET(self):
|
||||
if not self.do_AUTH():
|
||||
return
|
||||
|
||||
if self.path == "/":
|
||||
self.send_response(200)
|
||||
self.send_header("Content-type", "text/html")
|
||||
self.end_headers()
|
||||
|
||||
conf_path = _basedir / "../scrapeflows.conf"
|
||||
if conf_path.exists():
|
||||
with open(conf_path, "r", encoding="utf-8") as reader:
|
||||
filepath = _basedir / "../scrapeflows.conf"
|
||||
if filepath.exists():
|
||||
with open(filepath, "r", encoding="utf-8") as reader:
|
||||
saved_conf = json.load(reader)
|
||||
self.wfile.write(render_index(saved_conf).encode("utf-8"))
|
||||
else:
|
||||
self.wfile.write(_index_html.encode("utf-8"))
|
||||
|
||||
elif self.path.endswith("/exit"):
|
||||
elif self.path == "/exit":
|
||||
self.send_response(200)
|
||||
self.end_headers()
|
||||
self.server.server_close()
|
||||
sys.exit()
|
||||
|
||||
def do_POST(self):
|
||||
content_length = int(self.headers["Content-Length"])
|
||||
body = self.rfile.read(content_length)
|
||||
with open(_basedir / "../scrapeflows.conf", "w", encoding="utf-8") as w:
|
||||
w.write(body.decode("utf-8"))
|
||||
self.send_response(200)
|
||||
self.end_headers()
|
||||
if not self.do_AUTH():
|
||||
return
|
||||
|
||||
filepath = None
|
||||
if self.path == "/save":
|
||||
filepath = _basedir / "../scrapeflows.conf"
|
||||
elif self.path == "/auth":
|
||||
filepath = _basedir / "authorization"
|
||||
|
||||
if filepath is not None:
|
||||
content_length = int(self.headers["Content-Length"])
|
||||
body = self.rfile.read(content_length)
|
||||
with open(filepath, "w", encoding="utf-8") as w:
|
||||
w.write(body.decode("utf-8"))
|
||||
self.send_response(200)
|
||||
self.end_headers()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
@ -19,6 +19,12 @@
|
||||
<ion-icon name="open-outline"></ion-icon>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#auth" class="modal-trigger">
|
||||
Auth
|
||||
<ion-icon name="person-circle-outline"></ion-icon>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#exit" class="modal-trigger">
|
||||
Exit
|
||||
@ -68,6 +74,26 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="auth" class="modal">
|
||||
<div class="modal-content">
|
||||
<h6>Enable basic authentication?</h6>
|
||||
<div class="row">
|
||||
<div class="input-field col s6">
|
||||
<input id="username" type="text" class="validate">
|
||||
<label for="username">Username</label>
|
||||
</div>
|
||||
<div class="input-field col s6">
|
||||
<input id="password" type="password" class="validate">
|
||||
<label for="password">Password</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<a class="modal-close waves-effect btn-flat">Cancel</a>
|
||||
<a id="auth-btn" class="modal-close waves-effect waves-green btn-flat">Confirm</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/js/materialize.min.js"></script>
|
||||
<script type="module" src="https://unpkg.com/ionicons@7.1.0/dist/ionicons/ionicons.esm.js"></script>
|
||||
<script nomodule src="https://unpkg.com/ionicons@7.1.0/dist/ionicons/ionicons.js"></script>
|
||||
@ -99,10 +125,45 @@
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify(data)
|
||||
body: JSON.stringify(data, null, 2)
|
||||
}).then(response => {
|
||||
if (response.ok) {
|
||||
M.toast({ html: 'Save successful!', classes: 'center-align green lighten-2' })
|
||||
M.toast({
|
||||
html: 'Save successful!',
|
||||
classes: 'center-align green lighten-2',
|
||||
displayLength: 1000
|
||||
})
|
||||
} else {
|
||||
throw new Error(response.statusText);
|
||||
}
|
||||
}).catch(error => {
|
||||
M.toast({ html: error, classes: 'center-align red lighten-2' })
|
||||
});
|
||||
});
|
||||
|
||||
var authBtn = document.getElementById('auth-btn');
|
||||
authBtn.addEventListener('click', event => {
|
||||
event.preventDefault();
|
||||
|
||||
var username = document.getElementById('username').value;
|
||||
var password = document.getElementById('password').value;
|
||||
if (username == '' && password == '') {
|
||||
return;
|
||||
}
|
||||
|
||||
fetch('/auth', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: btoa(username + ':' + password)
|
||||
}).then(response => {
|
||||
if (response.ok) {
|
||||
M.toast({
|
||||
html: 'Authentication enabled!',
|
||||
classes: 'center-align green lighten-2',
|
||||
displayLength: 1000
|
||||
})
|
||||
} else {
|
||||
throw new Error(response.statusText);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user